├── .devcontainer
└── devcontainer.json
├── .github
├── dependabot.yml
└── workflows
│ ├── build.yml
│ ├── codeql.yml
│ ├── cypress.yml
│ ├── doc_to_pages.yml
│ ├── issue2project.yml
│ ├── publish.yml
│ ├── publish_doc.yml
│ ├── remove_triage.yml
│ ├── rm_action_runs.yml
│ ├── rm_cache.yml
│ ├── stale.yml
│ └── triage.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .vscode
├── extensions.json
└── settings.json
├── Dockerfile.dev
├── LICENSE
├── MANIFEST.in
├── README.md
├── doc
├── CN
│ ├── ML
│ │ ├── auto_inference.md
│ │ ├── install_ml.md
│ │ ├── interactive_segmentation.md
│ │ └── ml.md
│ ├── README.md
│ ├── _config.yml
│ ├── assets
│ │ ├── accept_model_label.png
│ │ ├── action-1.png
│ │ ├── add_label.png
│ │ ├── auto_inference.png
│ │ ├── classification.png
│ │ ├── cn_home.png
│ │ ├── create.png
│ │ ├── dataset_path.png
│ │ ├── dataset_split.png
│ │ ├── dont_accept_model_label.png
│ │ ├── export.png
│ │ ├── export_detail.png
│ │ ├── group_qr.png
│ │ ├── import_name.png
│ │ ├── interact_button.png
│ │ ├── interact_mode.png
│ │ ├── interact_setting.png
│ │ ├── label_page.png
│ │ ├── miniconda_cn.png
│ │ ├── miniconda_init_cn.png
│ │ ├── miniconda_install_type.png
│ │ ├── ml_backend_url.png
│ │ ├── msvc.png
│ │ ├── project_overview.png
│ │ ├── project_overview_to_label.png
│ │ ├── project_overview_to_split.png
│ │ ├── sample_button.png
│ │ ├── sample_page.png
│ │ ├── sample_structure.png
│ │ ├── start_two.png
│ │ ├── test_label.png
│ │ ├── to_auto_inference.png
│ │ ├── to_home.png
│ │ └── to_overview.png
│ ├── developers_guide.md
│ ├── install.md
│ ├── manual
│ │ ├── classification.md
│ │ ├── common.md
│ │ ├── detection.md
│ │ ├── instance_segmentation.md
│ │ ├── manual.md
│ │ ├── ocr.md
│ │ └── semantic_segmentation.md
│ ├── quick_start.md
│ ├── release_notes.md
│ └── training
│ │ ├── PdLabel_PdClas.md
│ │ ├── PdLabel_PdDet.md
│ │ ├── PdLabel_PdSeg.md
│ │ ├── PdLabel_PdX.md
│ │ └── training.md
├── EN
│ ├── README.md
│ ├── _config.yml
│ ├── assets
│ │ └── group_qr.png
│ ├── developers_guide.md
│ └── project
│ │ └── dataset_file_structure.md
├── Gemfile
├── README.md
├── old
│ ├── dataset_file_structure.md
│ └── detection_ml.md
└── prepare.py
├── docker-compose-dev.yml
├── docstring_format.mustache
├── paddlelabel
├── __init__.py
├── __main__.py
├── alembic.ini
├── api
│ ├── __init__.py
│ ├── controller
│ │ ├── __init__.py
│ │ ├── annotation.py
│ │ ├── base.py
│ │ ├── data.py
│ │ ├── label.py
│ │ ├── project.py
│ │ ├── sample.py
│ │ ├── setting.py
│ │ ├── tag.py
│ │ ├── task.py
│ │ └── user.py
│ ├── model
│ │ ├── __init__.py
│ │ ├── annotation.py
│ │ ├── base.py
│ │ ├── data.py
│ │ ├── label.py
│ │ ├── project.py
│ │ ├── setting.py
│ │ ├── tag.py
│ │ ├── tag_task.py
│ │ ├── task.py
│ │ └── user.py
│ ├── rpc
│ │ ├── __init__.py
│ │ ├── cache.py
│ │ ├── debug.py
│ │ ├── file.py
│ │ ├── monitor.py
│ │ ├── seg.py
│ │ └── util
│ │ │ ├── __init__.py
│ │ │ └── polygon.py
│ ├── schema
│ │ ├── __init__.py
│ │ ├── annotation.py
│ │ ├── base.py
│ │ ├── data.py
│ │ ├── label.py
│ │ ├── project.py
│ │ ├── setting.py
│ │ ├── tag.py
│ │ ├── tag_task.py
│ │ ├── task.py
│ │ ├── user.py
│ │ └── util.py
│ └── util.py
├── config.py
├── dbmigration
│ ├── README.md
│ ├── __init__.py
│ ├── env.py
│ ├── script.py.mako
│ └── versions
│ │ ├── 23c1bf9b7f48_v0_1_2.py
│ │ ├── 61968cbf48e8_v0_1_3.py
│ │ ├── __init__.py
│ │ ├── a609821ce310_v0_1_4.py
│ │ ├── e660f34b820d_v1_0_1.py
│ │ └── f47b7f5b73b9_v1_0_0.py
├── default_setting.json
├── io
│ ├── __init__.py
│ └── image.py
├── openapi.yml
├── sample
│ ├── bear
│ │ ├── classification
│ │ │ ├── multiClass
│ │ │ │ ├── labels.txt
│ │ │ │ ├── test_list.txt
│ │ │ │ ├── train_list.txt
│ │ │ │ └── val_list.txt
│ │ │ └── singleClass
│ │ │ │ ├── labels.txt
│ │ │ │ ├── test_list.txt
│ │ │ │ ├── train_list.txt
│ │ │ │ └── val_list.txt
│ │ ├── detection
│ │ │ ├── coco
│ │ │ │ ├── test.json
│ │ │ │ ├── train.json
│ │ │ │ └── val.json
│ │ │ ├── voc
│ │ │ │ ├── Annotations
│ │ │ │ │ ├── 1.xml
│ │ │ │ │ ├── 2.xml
│ │ │ │ │ └── 3.xml
│ │ │ │ ├── labels.txt
│ │ │ │ ├── test_list.txt
│ │ │ │ ├── train_list.txt
│ │ │ │ └── val_list.txt
│ │ │ └── yolo
│ │ │ │ ├── Annotations
│ │ │ │ ├── 1.txt
│ │ │ │ ├── 2.txt
│ │ │ │ └── 3.txt
│ │ │ │ ├── classes.names
│ │ │ │ ├── test_list.txt
│ │ │ │ ├── train_list.txt
│ │ │ │ └── val_list.txt
│ │ ├── img
│ │ │ ├── 05.jpg
│ │ │ ├── 06.jpg
│ │ │ ├── 07.jpg
│ │ │ ├── 08.jpg
│ │ │ ├── 09.jpg
│ │ │ ├── 1.jpeg
│ │ │ ├── 10.jpg
│ │ │ ├── 11.png
│ │ │ ├── 2.jpeg
│ │ │ ├── 3.jpeg
│ │ │ └── 4.jpeg
│ │ ├── instanceSegmentation
│ │ │ ├── coco
│ │ │ │ ├── test.json
│ │ │ │ ├── train.json
│ │ │ │ └── val.json
│ │ │ ├── eiseg
│ │ │ │ └── label
│ │ │ │ │ ├── 1.json
│ │ │ │ │ ├── 2.json
│ │ │ │ │ └── 3.json
│ │ │ └── mask
│ │ │ │ ├── Annotations
│ │ │ │ ├── 1.tiff
│ │ │ │ ├── 2.tiff
│ │ │ │ └── 3.tiff
│ │ │ │ ├── labels.txt
│ │ │ │ ├── test_list.txt
│ │ │ │ ├── train_list.txt
│ │ │ │ └── val_list.txt
│ │ ├── opticalCharacterRecognition
│ │ │ └── txt
│ │ │ │ └── Label.txt
│ │ ├── placeholder
│ │ │ ├── labels.txt
│ │ │ ├── test_list.txt
│ │ │ ├── train_list.txt
│ │ │ └── val_list.txt
│ │ ├── point
│ │ │ └── labelme
│ │ │ │ └── Annotations
│ │ │ │ ├── 1.json
│ │ │ │ ├── 2.json
│ │ │ │ ├── 3.json
│ │ │ │ └── 4.json
│ │ └── semanticSegmentation
│ │ │ ├── coco
│ │ │ ├── test.json
│ │ │ ├── train.json
│ │ │ └── val.json
│ │ │ ├── eiseg
│ │ │ └── label
│ │ │ │ ├── 1.json
│ │ │ │ ├── 2.json
│ │ │ │ └── 3.json
│ │ │ └── mask
│ │ │ ├── Annotations
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ └── 3.png
│ │ │ ├── labels.txt
│ │ │ ├── test_list.txt
│ │ │ ├── train_list.txt
│ │ │ └── val_list.txt
│ └── fruit
│ │ ├── classification
│ │ ├── multiClass
│ │ │ ├── labels.txt
│ │ │ ├── test_list.txt
│ │ │ ├── train_list.txt
│ │ │ └── val_list.txt
│ │ └── singleClass
│ │ │ ├── labels.txt
│ │ │ ├── paddlelabel.warning
│ │ │ ├── test_list.txt
│ │ │ ├── train_list.txt
│ │ │ └── val_list.txt
│ │ ├── detection
│ │ ├── coco
│ │ │ ├── test.json
│ │ │ ├── train.json
│ │ │ └── val.json
│ │ ├── voc
│ │ │ ├── Annotations
│ │ │ │ ├── 1.xml
│ │ │ │ ├── 2.xml
│ │ │ │ ├── 3.xml
│ │ │ │ └── 4.xml
│ │ │ ├── labels.txt
│ │ │ ├── test_list.txt
│ │ │ ├── train_list.txt
│ │ │ └── val_list.txt
│ │ └── yolo
│ │ │ ├── Annotations
│ │ │ ├── 1.txt
│ │ │ ├── 2.txt
│ │ │ ├── 3.txt
│ │ │ └── 4.txt
│ │ │ ├── classes.names
│ │ │ ├── test_list.txt
│ │ │ ├── train_list.txt
│ │ │ └── val_list.txt
│ │ ├── img
│ │ ├── 1.jpeg
│ │ ├── 2.jpeg
│ │ ├── 3.jpeg
│ │ ├── 4.jpeg
│ │ └── 5.jpeg
│ │ ├── instanceSegmentation
│ │ ├── coco
│ │ │ ├── test.json
│ │ │ ├── train.json
│ │ │ └── val.json
│ │ └── mask
│ │ │ ├── Annotations
│ │ │ ├── 1.tiff
│ │ │ ├── 2.tiff
│ │ │ ├── 3.tiff
│ │ │ └── 4.tiff
│ │ │ ├── labels.txt
│ │ │ ├── test_list.txt
│ │ │ ├── train_list.txt
│ │ │ └── val_list.txt
│ │ ├── placeholder
│ │ ├── labels.txt
│ │ ├── paddlelabel.warning
│ │ ├── test_list.txt
│ │ ├── train_list.txt
│ │ └── val_list.txt
│ │ └── semanticSegmentation
│ │ ├── coco
│ │ ├── test.json
│ │ ├── train.json
│ │ └── val.json
│ │ └── mask
│ │ ├── Annotations
│ │ ├── 1.png
│ │ ├── 2.png
│ │ ├── 3.png
│ │ └── 4.png
│ │ ├── labels.txt
│ │ ├── test_list.txt
│ │ ├── train_list.txt
│ │ └── val_list.txt
├── serve.py
├── task
│ ├── __init__.py
│ ├── base.py
│ ├── classification.py
│ ├── detection.py
│ ├── instance_segmentation.py
│ ├── optical_character_recognition.py
│ ├── point.py
│ ├── semantic_segmentation.py
│ └── util
│ │ ├── __init__.py
│ │ ├── color.py
│ │ ├── file.py
│ │ ├── labelme.py
│ │ └── manager.py
├── tool
│ ├── __main__.py
│ └── simple_file_format.py
├── util.py
└── version
├── pyproject.toml
├── pyproject.toml.temp
├── requirements-dev.txt
├── requirements.txt
├── setup.py
├── thunder-tests
├── thunderActivity.json
├── thunderCollection.json
├── thunderEnvironment.json
└── thunderclient.json
└── tool
├── build_frontend.sh
├── bumpversion.py
├── file.py
├── gen_sample_dst.py
├── get_frontend.sh
├── old
├── Procfile
├── clas
│ ├── __init__.py
│ └── mv_image_acc_split.py
├── cypress.sh
├── freeze_env.sh
├── install.sh
├── kill_by_port.py
├── labels
│ └── labels_remove_first_value.py
├── pypi.sh
├── rm_workflow_runs.sh
└── runtime.txt
└── zip_sample.sh
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | {
2 | "dockerComposeFile": [
3 | "../docker-compose-dev.yml"
4 | ],
5 | "extensions": [
6 | "dbaeumer.vscode-eslint",
7 | "ms-python.vscode-pylance",
8 | "ms-python.python"
9 | ],
10 | "features": {
11 | "git": "os-provided",
12 | "github-cli": "latest",
13 | "sshd": "latest"
14 | },
15 | "forwardPorts": [
16 | 5000
17 | ],
18 | "name": "backend-pp-label-vscode",
19 | "service": "pp-labeling-backend",
20 | "settings": {},
21 | "workspaceFolder": "/app"
22 | }
23 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: "pip" # See documentation for possible values
9 | directory: "/requirements.txt" # Location of package manifests
10 | schedule:
11 | interval: "weekly"
12 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build & E2E Tests
2 |
3 | on:
4 | push:
5 | branches:
6 | - develop
7 | pull_request:
8 | branches:
9 | - v*
10 | workflow_dispatch:
11 | inputs:
12 | force_regen_doc:
13 | description: "Force regenerate doc site"
14 | required: false
15 | default: true
16 | type: boolean
17 | schedule:
18 | - cron: "0 12 * * *"
19 |
20 | jobs:
21 | update_doc_build:
22 | # uses: PaddleCV-SIG/PaddleLabel/.github/workflows/doc_to_pages.yml@develop
23 | uses: ./.github/workflows/doc_to_pages.yml
24 | with:
25 | baseurl: "/static/doc/"
26 | deploy: false
27 | # force_regen: ${{ inputs.force_regen_doc }}
28 | force_regen: true
29 |
30 | build:
31 | runs-on: ubuntu-latest
32 | strategy:
33 | matrix:
34 | python-version: ["3.11"]
35 |
36 | needs: update_doc_build
37 | steps:
38 | - name: Checkout backend code
39 | uses: actions/checkout@v3
40 |
41 | - name: Download built frontend
42 | uses: dawidd6/action-download-artifact@v2
43 | with:
44 | workflow: build.yml
45 | workflow_conclusion: success
46 | repo: PaddleCV-SIG/PaddleLabel-Frontend
47 | name: PaddleLabel_built_frontend
48 | path: ./paddlelabel/static/
49 | search_artifacts: true
50 |
51 | - name: Download built doc static site
52 | uses: actions/download-artifact@v3
53 | # uses: dawidd6/action-download-artifact@v2
54 | with:
55 | # workflow_conclusion: ""
56 | # branch: develop
57 | name: github-pages
58 | # search_artifacts: true
59 | # check_artifacts: true
60 | path: ./paddlelabel/static/doc/
61 |
62 | - name: Unarchive doc site
63 | run: |
64 | cd ./paddlelabel/static/doc/
65 | ls
66 | tar -xvf artifact.tar
67 | rm artifact.tar
68 | tree .
69 | cd -
70 |
71 | - name: Set up Python ${{ matrix.python-version }}
72 | uses: actions/setup-python@v4
73 | with:
74 | python-version: ${{ matrix.python-version }}
75 | cache: "pip"
76 |
77 | - name: Install dependencies
78 | run: |
79 | python -m pip install --upgrade pip
80 | pip install --upgrade twine wheel
81 |
82 | - name: Write backend commit hash to package
83 | run: |
84 | echo backend $(git rev-parse --short HEAD) >> ./paddlelabel/static/git_versions.html
85 |
86 | - name: Generate package
87 | run: |
88 | python setup.py sdist bdist_wheel
89 |
90 | - name: Set action summary
91 | run: |
92 | echo "
93 | # Build Summary
94 | branch: $(git branch --show-current)
95 | version: $(cat paddlelabel/version)
96 | " >> $GITHUB_STEP_SUMMARY
97 |
98 | - name: Save built package
99 | uses: actions/upload-artifact@v3
100 | with:
101 | name: PaddleLabel_built_package
102 | path: |
103 | dist
104 |
105 | cypress_e2e_test:
106 | needs: build
107 | # uses: PaddleCV-SIG/PaddleLabel/.github/workflows/cypress.yml@develop
108 | uses: ./.github/workflows/cypress.yml
109 |
110 | bump_version:
111 | if: github.event_name == 'push'
112 | runs-on: ubuntu-latest
113 | strategy:
114 | matrix:
115 | python-version: ["3.11"]
116 | needs: cypress_e2e_test
117 | steps:
118 | - name: Checkout backend code
119 | uses: actions/checkout@v3
120 |
121 | - name: Bump version
122 | id: bump_version
123 | # if: github.event_name == 'push'
124 | run: |
125 | python tool/bumpversion.py
126 | git config --global user.email "bot@github.com" && git config --global user.name "Action Bot"
127 | git add paddlelabel/version; git commit -m "bump version"; git push
128 |
--------------------------------------------------------------------------------
/.github/workflows/codeql.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [v*]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [v*]
20 | schedule:
21 | - cron: "31 15 * * 5"
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: ["python"]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
37 | # Use only 'java' to analyze code written in Java, Kotlin or both
38 | # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
39 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
40 |
41 | steps:
42 | - name: Checkout repository
43 | uses: actions/checkout@v3
44 |
45 | # Initializes the CodeQL tools for scanning.
46 | - name: Initialize CodeQL
47 | uses: github/codeql-action/init@v2
48 | with:
49 | languages: ${{ matrix.language }}
50 | # If you wish to specify custom queries, you can do so here or in a config file.
51 | # By default, queries listed here will override any specified in a config file.
52 | # Prefix the list here with "+" to use these queries and those in the config file.
53 |
54 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
55 | # queries: security-extended,security-and-quality
56 |
57 | # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
58 | # If this step fails, then you should remove it and run the build manually (see below)
59 | - name: Autobuild
60 | uses: github/codeql-action/autobuild@v2
61 |
62 | # ℹ️ Command-line programs to run using the OS shell.
63 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
64 |
65 | # If the Autobuild fails above, remove it and uncomment the following three lines.
66 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
67 |
68 | # - run: |
69 | # echo "Run, Build Application using script"
70 | # ./location_of_script_within_repo/buildscript.sh
71 |
72 | - name: Perform CodeQL Analysis
73 | uses: github/codeql-action/analyze@v2
74 | with:
75 | category: "/language:${{matrix.language}}"
76 |
--------------------------------------------------------------------------------
/.github/workflows/issue2project.yml:
--------------------------------------------------------------------------------
1 | name: Add issues to project
2 |
3 | on:
4 | issues:
5 | types:
6 | - opened
7 |
8 | jobs:
9 | add-to-project:
10 | name: Add issue to project
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/add-to-project@v0.3.0
14 | with:
15 | project-url: https://github.com/orgs/PaddleCV-SIG/projects/2
16 | github-token: ${{ secrets.ADD_TO_PROJECT_PAT }}
17 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publishing latest built package to pypi
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | dry_run:
7 | description: "Skip last publish step"
8 | required: false
9 | default: true
10 | type: boolean
11 | jobs:
12 | publish:
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - name: Download artifact
17 | id: download-artifact
18 | uses: dawidd6/action-download-artifact@v2
19 | with:
20 | workflow: build.yml
21 | workflow_conclusion: success
22 | branch: develop
23 | name: PaddleLabel_built_package
24 | path: |
25 | dist
26 |
27 | - run: |
28 | pwd
29 | ls
30 | tree .
31 |
32 | - name: Publish to PyPI
33 | if: ${{ inputs.dry_run != true }}
34 | uses: pypa/gh-action-pypi-publish@release/v1
35 | with:
36 | user: __token__
37 | password: ${{ secrets.PADDLELABEL_PUBLISH_API_TOKEN }}
38 | verbose: true
39 |
--------------------------------------------------------------------------------
/.github/workflows/publish_doc.yml:
--------------------------------------------------------------------------------
1 | name: Publish doc to pages
2 |
3 | on:
4 | push:
5 | branches:
6 | - develop
7 | - doc
8 | workflow_dispatch:
9 | inputs:
10 | force_regen:
11 | description: "Force the jekyll generation step"
12 | required: false
13 | default: true
14 | type: boolean
15 |
16 |
17 | jobs:
18 | publish_doc:
19 | uses: PaddleCV-SIG/PaddleLabel/.github/workflows/doc_to_pages.yml@develop
20 | with:
21 | baseurl: "/PaddleLabel/"
22 | deploy: true
23 | force_regen: ${{ inputs.force_regen }}
24 |
--------------------------------------------------------------------------------
/.github/workflows/remove_triage.yml:
--------------------------------------------------------------------------------
1 | name: Remove triage label
2 | on:
3 | issues:
4 | types:
5 | - assigned
6 | jobs:
7 | remove_label:
8 | runs-on: ubuntu-latest
9 | permissions:
10 | issues: write
11 | steps:
12 | - uses: actions/github-script@v6
13 | with:
14 | script: |
15 | github.rest.issues.removeLabel({
16 | issue_number: context.issue.number,
17 | owner: context.repo.owner,
18 | repo: context.repo.repo,
19 | name: ["triage"]
20 | })
21 |
--------------------------------------------------------------------------------
/.github/workflows/rm_action_runs.yml:
--------------------------------------------------------------------------------
1 | name: Delete old workflow runs
2 | on:
3 | workflow_dispatch:
4 | inputs:
5 | days:
6 | description: 'Number of days.'
7 | required: true
8 | default: 30
9 | minimum_runs:
10 | description: 'The minimum runs to keep for each workflow.'
11 | required: true
12 | default: 6
13 | delete_workflow_pattern:
14 | description: 'The name or filename of the workflow. if not set then it will target all workflows.'
15 | required: false
16 | delete_workflow_by_state_pattern:
17 | description: 'Remove workflow by state: active, deleted, disabled_fork, disabled_inactivity, disabled_manually'
18 | required: true
19 | default: "All"
20 | type: choice
21 | options:
22 | - "All"
23 | - active
24 | - deleted
25 | - disabled_inactivity
26 | - disabled_manually
27 | delete_run_by_conclusion_pattern:
28 | description: 'Remove workflow by conclusion: action_required, cancelled, failure, skipped, success'
29 | required: true
30 | default: "All"
31 | type: choice
32 | options:
33 | - "All"
34 | - action_required
35 | - cancelled
36 | - failure
37 | - skipped
38 | - success
39 | dry_run:
40 | description: 'Only log actions, do not perform any delete operations.'
41 | required: false
42 |
43 | jobs:
44 | del_runs:
45 | runs-on: ubuntu-latest
46 | steps:
47 | - name: Delete workflow runs
48 | uses: Mattraks/delete-workflow-runs@v2
49 | with:
50 | token: ${{ github.token }}
51 | repository: ${{ github.repository }}
52 | retain_days: ${{ github.event.inputs.days }}
53 | keep_minimum_runs: ${{ github.event.inputs.minimum_runs }}
54 | delete_workflow_pattern: ${{ github.event.inputs.delete_workflow_pattern }}
55 | delete_workflow_by_state_pattern: ${{ github.event.inputs.delete_workflow_by_state_pattern }}
56 | delete_run_by_conclusion_pattern: ${{ github.event.inputs.delete_run_by_conclusion_pattern }}
57 | dry_run: ${{ github.event.inputs.dry_run }}
58 |
--------------------------------------------------------------------------------
/.github/workflows/rm_cache.yml:
--------------------------------------------------------------------------------
1 | name: Delete All Caches
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | - cron: "0 0 * * SUN"
7 |
8 | jobs:
9 | delete:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: snnaplab/delete-branch-cache-action@v1
13 | # with:
14 | # # Specify explicitly because the ref at the time of merging will be a branch name such as 'main', 'develop'
15 | # ref: refs/pull/${{ github.event.number }}/merge
16 |
--------------------------------------------------------------------------------
/.github/workflows/stale.yml:
--------------------------------------------------------------------------------
1 | # This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
2 | #
3 | # You can adjust the behavior by modifying this file.
4 | # For more information, see:
5 | # https://github.com/actions/stale
6 | name: Mark stale issues and pull requests
7 |
8 | on:
9 | schedule:
10 | - cron: '0 17 * * *'
11 |
12 | jobs:
13 | stale:
14 |
15 | runs-on: ubuntu-latest
16 | permissions:
17 | issues: write
18 | pull-requests: none
19 |
20 | steps:
21 | - uses: actions/stale@v5
22 | with:
23 | repo-token: ${{ secrets.GITHUB_TOKEN }}
24 | stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.'
25 | stale-issue-label: 'stale'
26 | close-issue-reason: 'completed'
27 | exempt-issue-labels: 'bug, enhancement, Feature Request, WIP, TobeReviewed'
28 | operations-per-run: 900
29 | days-before-pr-stale: -1
30 | days-before-pr-close: -1
31 | ascending: true
32 |
--------------------------------------------------------------------------------
/.github/workflows/triage.yml:
--------------------------------------------------------------------------------
1 | name: Label issues
2 | on:
3 | issues:
4 | types:
5 | - reopened
6 | - opened
7 | jobs:
8 | label_issues:
9 | runs-on: ubuntu-latest
10 | permissions:
11 | issues: write
12 | steps:
13 | - uses: actions/github-script@v6
14 | with:
15 | script: |
16 | github.rest.issues.addLabels({
17 | issue_number: context.issue.number,
18 | owner: context.repo.owner,
19 | repo: context.repo.repo,
20 | labels: ["triage"]
21 | })
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Project Specific
2 | pplabel.db
3 | paddlelabel.db
4 | static/
5 | temp/
6 | temp
7 | test.py
8 | *.log
9 | *.test
10 |
11 | paddlelabel.warning
12 |
13 | _site
14 | .jekyll-cache
15 | Gemfile.lock
16 |
17 | # Byte-compiled / optimized / DLL files
18 | __pycache__/
19 | *.py[cod]
20 | *$py.class
21 | *.db
22 |
23 | # C extensions
24 | *.so
25 |
26 | # Distribution / packaging
27 | .Python
28 | build/
29 | develop-eggs/
30 | dist/
31 | downloads/
32 | eggs/
33 | .eggs/
34 | lib/
35 | lib64/
36 | parts/
37 | sdist/
38 | var/
39 | wheels/
40 | pip-wheel-metadata/
41 | share/python-wheels/
42 | *.egg-info/
43 | .installed.cfg
44 | *.egg
45 | MANIFEST
46 |
47 | # PyInstaller
48 | # Usually these files are written by a python script from a template
49 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
50 | *.manifest
51 | *.spec
52 |
53 | # Installer logs
54 | pip-log.txt
55 | pip-delete-this-directory.txt
56 |
57 | # Unit test / coverage reports
58 | htmlcov/
59 | .tox/
60 | .nox/
61 | .coverage
62 | .coverage.*
63 | .cache
64 | nosetests.xml
65 | coverage.xml
66 | *.cover
67 | *.py,cover
68 | .hypothesis/
69 | .pytest_cache/
70 |
71 | # Translations
72 | *.mo
73 | *.pot
74 |
75 | # Django stuff:
76 | *.log
77 | local_settings.py
78 | db.sqlite3
79 | db.sqlite3-journal
80 |
81 | # Flask stuff:
82 | instance/
83 | .webassets-cache
84 |
85 | # Scrapy stuff:
86 | .scrapy
87 |
88 | # Sphinx documentation
89 | docs/_build/
90 |
91 | # PyBuilder
92 | target/
93 |
94 | # Jupyter Notebook
95 | .ipynb_checkpoints
96 |
97 | # IPython
98 | profile_default/
99 | ipython_config.py
100 |
101 | # pyenv
102 | .python-version
103 |
104 | # pipenv
105 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
106 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
107 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
108 | # install all needed dependencies.
109 | #Pipfile.lock
110 |
111 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
112 | __pypackages__/
113 |
114 | # Celery stuff
115 | celerybeat-schedule
116 | celerybeat.pid
117 |
118 | # SageMath parsed files
119 | *.sage.py
120 |
121 | # Environments
122 | .env
123 | .venv
124 | env/
125 | venv/
126 | ENV/
127 | env.bak/
128 | venv.bak/
129 |
130 | # Spyder project settings
131 | .spyderproject
132 | .spyproject
133 |
134 | # Rope project settings
135 | .ropeproject
136 |
137 | # mkdocs documentation
138 | /site
139 |
140 | # mypy
141 | .mypy_cache/
142 | .dmypy.json
143 | dmypy.json
144 |
145 | # Pyre type checker
146 | .pyre/
147 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | repos:
2 | - repo: https://github.com/pre-commit/pre-commit-hooks
3 | rev: v4.3.0
4 | hooks:
5 | - id: no-commit-to-branch
6 | args: [--pattern, ^v]
7 | # - id: check-added-large-files
8 | # args: [--maxkb=16]
9 | - id: check-case-conflict
10 | - id: check-yaml
11 | - id: check-xml
12 | - id: check-toml
13 | - id: check-merge-conflict
14 | - id: check-symlinks
15 | - id: destroyed-symlinks
16 | - id: mixed-line-ending
17 | args: [--fix=lf]
18 | - id: end-of-file-fixer
19 | - id: trailing-whitespace
20 | - id: check-json
21 | - id: pretty-format-json
22 | args: [--autofix, --indent=4, --no-ensure-ascii]
23 | # - id: detect-aws-credentials
24 | - id: detect-private-key
25 | - id: fix-encoding-pragma
26 |
27 | # - repo: https://github.com/pre-commit/mirrors-mypy
28 | # rev: v0.991
29 | # hooks:
30 | # - id: mypy
31 | - repo: https://github.com/psf/black
32 | rev: 22.10.0
33 | hooks:
34 | - id: black
35 |
36 | - repo: https://github.com/pre-commit/pygrep-hooks
37 | rev: v1.10.0 # Use the ref you want to point at
38 | hooks:
39 | - id: python-use-type-annotations
40 |
41 |
42 | # - repo: https://github.com/sonatype-nexus-community/jake
43 | # rev: "v3.0.0"
44 | # hooks:
45 | # - id: scan
46 | # - repo: https://github.com/executablebooks/mdformat
47 | # rev: 0.7.16 # Use the ref you want to point at
48 | # hooks:
49 | # - id: mdformat
50 | # exclude: doc/CN/project/detection.md # messes up image['file_name']
51 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "dotjoshjohnson.xml",
4 | "njpwerner.autodocstring",
5 | "pejmannikram.vscode-auto-scroll",
6 | "streetsidesoftware.code-spell-checker",
7 | "fabiospampinato.vscode-highlight",
8 | "redhat.vscode-yaml",
9 | "ms-python.isort",
10 | "yzhang.markdown-all-in-one",
11 | "ms-python.vscode-pylance",
12 | "ms-python.python"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "autoDocstring.customTemplatePath": "docstring_format.mustache",
3 | "cSpell.words": [
4 | "anns",
5 | "autofix",
6 | "bgid",
7 | "bndbox",
8 | "callouts",
9 | "catg",
10 | "catgs",
11 | "choco",
12 | "Clas",
13 | "conda",
14 | "connexion",
15 | "datas",
16 | "dawidd",
17 | "dbmigration",
18 | "dsts",
19 | "dtype",
20 | "easydata",
21 | "eiseg",
22 | "imread",
23 | "jemoji",
24 | "labelme",
25 | "levelname",
26 | "linhandev",
27 | "micromamba",
28 | "miniconda",
29 | "msvc",
30 | "msys",
31 | "nncol",
32 | "noviz",
33 | "numpy",
34 | "ondelete",
35 | "onupdate",
36 | "outcoco",
37 | "pacman",
38 | "paddlelabel",
39 | "paddlelabl",
40 | "paddlepaddle",
41 | "pdlabel",
42 | "Pico",
43 | "pjid",
44 | "pkgs",
45 | "popleft",
46 | "PPLC",
47 | "pycocotoolse",
48 | "pypi",
49 | "regen",
50 | "rget",
51 | "SQLALCHEMY",
52 | "supercategory",
53 | "vcbuildtools",
54 | "vcredist",
55 | "venv",
56 | "werkzeug",
57 | "xlen",
58 | "xmax",
59 | "xmid",
60 | "xmin",
61 | "ylen",
62 | "ymax",
63 | "ymid",
64 | "ymin",
65 | "yolo"
66 | ],
67 | "python.analysis.diagnosticMode": "workspace",
68 | "python.analysis.typeCheckingMode": "basic",
69 | "python.formatting.provider": "black",
70 | "python.languageServer": "Pylance"
71 | }
72 |
--------------------------------------------------------------------------------
/Dockerfile.dev:
--------------------------------------------------------------------------------
1 | FROM python:3.9
2 |
3 | WORKDIR /app
4 | # ADD . .
5 |
6 | # Keeps Python from generating .pyc files in the container
7 | ENV PYTHONDONTWRITEBYTECODE=1
8 |
9 | # Turns off buffering for easier container logging
10 | ENV PYTHONUNBUFFERED=1
11 |
12 | # Important Install For GDAL
13 | RUN apt-get update \
14 | && apt-get install -y gdal-bin libgdal-dev
15 |
16 | RUN export CPLUS_INCLUDE_PATH=/usr/include/gdal
17 | RUN export C_INCLUDE_PATH=/usr/include/gdal
18 |
19 | # Install requirements
20 | COPY ./requirements.txt .
21 | RUN pip install --upgrade pip
22 | RUN pip install -r requirements.txt
23 |
24 | # Add source code
25 |
26 | # Set environment variables
27 | # ENV FLASK_APP=setup.py
28 |
29 | # Run
30 | ENTRYPOINT [ "python", "-m", "paddlelabel" ]
31 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | recursive-include paddlelabel/sample/ *
2 | recursive-include paddlelabel/static/ *
3 |
4 | include paddlelabel/alembic.ini
5 | include paddlelabel/dbmigration/script.py.mako
6 | include paddlelabel/version
7 | include paddlelabel/default_setting.json
8 | include paddlelabel/openapi.yml
9 | include requirements.txt
10 |
11 | # exclude test/
12 | # exclude tool/
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | doc/CN/README.md
--------------------------------------------------------------------------------
/doc/CN/ML/auto_inference.md:
--------------------------------------------------------------------------------
1 | # 自动预标注使用方法
2 |
3 |
4 |
5 | - [模型列表](#%E6%A8%A1%E5%9E%8B%E5%88%97%E8%A1%A8)
6 | - [前置步骤](#%E5%89%8D%E7%BD%AE%E6%AD%A5%E9%AA%A4)
7 | - [进行设置](#%E8%BF%9B%E8%A1%8C%E8%AE%BE%E7%BD%AE)
8 | - [使用自动预标注](#%E4%BD%BF%E7%94%A8%E8%87%AA%E5%8A%A8%E9%A2%84%E6%A0%87%E6%B3%A8)
9 |
10 |
11 |
12 | PaddleLabel 基于 [PaddleClas](https://github.com/PaddlePaddle/PaddleClas),[PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection) 和 [PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR) 中的预训练模型为分类,检测和 OCR 项目提供自动预标注能力。您只需在“自动推理设置”中进行简单配置即可启用这一功能。本文档以分类项目为例介绍自动预标注功能的配置和使用方法,检测和 OCR 项目中的使用流程基本完全相同。
13 |
14 | 
15 |
16 |
22 |
23 | ## 模型列表
24 |
25 | PaddleLabel 目前支持的模型和使用各模型所需的 PaddleLabel-ML 版本如下
26 |
27 | - 分类
28 | - [PP-LCNetV2](https://github.com/PaddlePaddle/PaddleClas/blob/release/2.5/docs/zh_CN/models/ImageNet1k/PP-LCNetV2.md)
29 | v0.5.0+ {: .label }
30 | - 检测
31 | - [PP-PicoDet](https://github.com/PaddlePaddle/PaddleDetection/tree/release/2.5/configs/picodet)
32 | v0.5.0+ {: .label }
33 | - OCR
34 | - [PP-OCRv3](https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.6/doc/doc_ch/PP-OCRv3_introduction.md)
35 | v0.5.0+ {: .label }
36 |
37 | ## 前置步骤
38 |
39 | 1. 在使用自动预标注功能前请先参考 [此文档](/doc/CN/ML/install_ml.md) 安装 PaddleLabel-ML 辅助标注后端
40 |
41 | 2. 启动 PaddleLabel 和 PaddleLabel-ML
42 |
43 | 打开两个命令行终端,第一个输入 `paddlelabel` 并回车,第二个输入 `paddlelabel-ml` 并回车,分别启动项目的 web 部分和辅助标注部分
44 | 
45 |
46 | 3. 创建项目
47 |
48 | 您可以参考快速体验文档[创建内置样例项目](/doc/CN/quick_start.md#创建样例项目)或[导入一个数据集](/doc/CN/quick_start.md#导入数据集)
49 |
50 | ## 进行设置
51 |
52 | 1. 点击“项目总览”页面上方“自动推理设置”按钮进入设置页面
53 | 
54 | 2. 填写机器学习后端网址
55 |
56 | 默认网址为`http://127.0.0.1:1234`。这一网址可以通过观察 paddlelabel-ml 启动时的命令行输出确定
57 | 
58 |
59 | 3. 点击模型选择下拉菜单选择一个模型
60 | 4. 选择是否使用预标注标签
61 |
62 | - 此处如选择`是`
63 | - 预标注模型的推理结果类别将被原样添加到图像标注中
64 | - 如果模型推理出了一个项目中没有的类别,会自动向项目中添加该类别标签
65 | 
66 | - 此处如选择`否`,则不直接使用预标注模型标签
67 | - 您需要提供预标注模型标签与项目中标签的对应关系。比如指定预标注模型的标签“咖啡杯”对应项目中的标签“杯子”,标注时如果模型对一张图片推理结果为“咖啡杯”,则会向该图片添加“杯子”类别
68 | - 多个预标注模型的标签可以对应同一个项目中的标签,比如使用下图中的配置,“咖啡壶”和“咖啡杯”类别的推理结果都会向图片中添加“咖啡用具”标签
69 | - 一个模型标签只能对应到一个项目中的标签
70 | - 注意在这个模式下,辅助标注流程会忽略所有未提供对应关系的预标注模型标签
71 | 
72 |
73 | 5. 完成设置后,点击`确定`保存,跳转回项目总览页面
74 |
75 | ## 使用自动预标注
76 |
77 | - 预标注模型会在您进入标注页面时自动加载
78 | - 当您翻到一张之前没有进行过预标注的图片时会自动触发推理。您也可以点击右侧工具栏中的“自动推理”按钮手动触发一次推理
79 | - 您可以通过调节右侧工具栏中的“推理阈值”控制预标注结果的数量
80 |
--------------------------------------------------------------------------------
/doc/CN/ML/install_ml.md:
--------------------------------------------------------------------------------
1 | # 机器学习后端安装
2 |
3 |
4 |
5 | - [前置步骤](#%E5%89%8D%E7%BD%AE%E6%AD%A5%E9%AA%A4)
6 | - [安装方式](#%E5%AE%89%E8%A3%85%E6%96%B9%E5%BC%8F)
7 | - [通过 pip 安装](#%E9%80%9A%E8%BF%87-pip-%E5%AE%89%E8%A3%85)
8 | - [下载最新开发版](#%E4%B8%8B%E8%BD%BD%E6%9C%80%E6%96%B0%E5%BC%80%E5%8F%91%E7%89%88)
9 | - [通过源码安装](#%E9%80%9A%E8%BF%87%E6%BA%90%E7%A0%81%E5%AE%89%E8%A3%85)
10 | - [启动](#%E5%90%AF%E5%8A%A8)
11 | - [更多启动选项](#%E6%9B%B4%E5%A4%9A%E5%90%AF%E5%8A%A8%E9%80%89%E9%A1%B9)
12 | - [下一步](#%E4%B8%8B%E4%B8%80%E6%AD%A5)
13 |
14 |
15 |
16 | ## 前置步骤
17 |
18 | 为了避免环境冲突,建议首先创建一个新的虚拟环境。
19 |
20 | ```python
21 | conda create -n paddlelabel-ml python=3.10
22 | conda activate paddlelabel-ml
23 | ```
24 |
25 | 您可以选择安装 cpu 或 gpu 版本的 PaddlePaddle,cpu 版本安装简便,首次尝试推荐安装这一版本;gpu 版本推理速度更快,重度使用时体验更好。推荐安装不低于 2.2.0 版本的 PaddlePaddle。
26 |
27 | cpu 版本
28 |
29 | ```shell
30 | pip install paddlepaddle
31 | ```
32 |
33 | gpu 版本
34 |
35 | ```shell
36 |
37 | ```
38 |
39 |
40 |
41 | ## 安装方式
42 |
43 | 与 PaddleLabel 类似,您可以通过以下三种方式中的**任意一种**安装 PaddleLabel-ML,其中通过 pip 安装最简单。
44 |
45 | ### 通过 pip 安装
46 |
47 | ```shell
48 | pip install --upgrade paddlelabel-ml
49 | ```
50 |
51 | 看到类似于 `Successfully installed paddlelabel-ml-0.5.0` 的命令行输出即为安装成功,您可以直接继续浏览[启动](#%E5%90%AF%E5%8A%A8)章节。
52 |
53 | {: .note }
54 | **以下两种安装方式主要针对二次开发场景**
55 |
56 | ### 下载最新开发版
57 |
58 | 详细步骤
59 | 每当 PaddleLabel-ML 的代码有更新,项目的 Github Action 脚本都会构建一个反映最新版代码的安装包。这一安装包未经过全面测试,因此很可能存在一些问题,仅推荐为尝试最新版本使用。其中可能修复了一些 pypi 版本中存在的问题,添加了一些新功能或进行了一些性能提升。
60 |
61 | 下载方式为
62 |
63 |
64 |
65 | 1. 访问 [Action 执行记录网页](https://github.com/PaddleCV-SIG/PaddleLabel-ML/actions/workflows/build.yml)
66 | 2. 选择最上面(最新)的一条执行记录,点击进入
67 | 
68 | 3. 滑到页面最下方,点击下载
69 | PaddleLabel-ML_built_package 压缩包
70 | 
71 | 4. 解压该压缩包,之后执行
72 |
73 | ```shell
74 | pip install [解压出的.whl文件名,如 paddlelabel-ml-0.5.0-py3-none-any.whl ]
75 | ```
76 |
77 |
78 |
79 | ### 通过源码安装
80 |
81 | 详细步骤
82 |
83 |
84 |
85 |
86 |
87 | ## 启动
88 |
89 | 完成上述的安装操作后,可以直接在终端使用如下指令启动 PaddleLabel-ML
90 |
91 | ```shell
92 | paddlelabel-ml # 启动paddlelabel-ml
93 | ```
94 |
95 | 看到类似 `PaddleLabel-ML is running at http://localhost:1234` 的输出即为启动成功。您也可以访问[http://localhost:1234/running](http://localhost:1234/running)网页确定 ML 后端是否启动成功。
96 |
97 | {: .note}
98 | PaddleLabel-ML 没有独立的前端网页,您可以继续浏览[机器学习辅助标注](/doc/CN/ML/ml.md)章节了解如何在各个类型项目中配置和使用机器学习辅助标注功能。
99 |
100 | ### 更多启动选项
101 |
102 | PaddleLabel-ML 的默认运行网址为[http://localhost:1234](http://localhost:1234)。如果该端口已被占用,可以通过`--port`或`-p`参数指定其他端口。此外可以通过`--lan`或`-l`参数将服务暴露到局域网。在 docker 中运行 PaddleLabel 时也需要添加`--lan`参数。
103 |
104 | ```shell
105 | paddlelabel --port 6000 --lan # 在6000端口上运行并将服务暴露到局域网
106 | ```
107 |
108 | 更多启动参数可以使用 `paddlelabel-ml -h` 查看。
109 |
110 | ## 下一步
111 |
112 | 恭喜您成功运行 PaddleLabel 机器学习辅助标注后端!您可以继续浏览[机器学习辅助标注](/doc/CN/ML/ml.md)章节了解如何在各个类型项目中配置和使用辅助标注功能。
113 |
--------------------------------------------------------------------------------
/doc/CN/ML/interactive_segmentation.md:
--------------------------------------------------------------------------------
1 | # 交互式分割使用方法
2 |
3 |
4 |
5 | - [前置步骤](#%E5%89%8D%E7%BD%AE%E6%AD%A5%E9%AA%A4)
6 | - [进行设置](#%E8%BF%9B%E8%A1%8C%E8%AE%BE%E7%BD%AE)
7 | - [使用交互式标注](#%E4%BD%BF%E7%94%A8%E4%BA%A4%E4%BA%92%E5%BC%8F%E6%A0%87%E6%B3%A8)
8 |
9 |
10 |
11 |
12 |
13 | PaddleLabel 基于[EdgeFlow](https://arxiv.org/abs/2109.09406)模型在语义和实例分割项目中提供交互式分割支持。
14 |
15 | ## 前置步骤
16 |
17 | 1. 在使用自动预标注功能前请先参考 [此文档](/doc/CN/ML/install_ml.md) 安装 PaddleLabel-ML 辅助标注后端
18 |
19 | 2. 启动 PaddleLabel 和 PaddleLabel-ML
20 |
21 | 打开两个命令行终端,第一个输入 `paddlelabel` 并回车,第二个输入 `paddlelabel-ml` 并回车,分别启动项目的 web 部分和辅助标注部分
22 | 
23 |
24 | 3. 创建项目
25 |
26 | 您可以参考快速体验文档[创建内置样例项目](/doc/CN/quick_start.md#创建样例项目)或[导入一个数据集](/doc/CN/quick_start.md#导入数据集)
27 |
28 | ## 进行设置
29 |
30 | 1. 创建项目后直接进入标注页面,当鼠标悬浮在右侧工具栏“交互式分割”按钮上时,其左侧会出现“交互式分割设置”按钮,点击该按钮将弹出设置面板。
31 | 
32 | 
33 | 2. 交互式分割设置中,机器学习后端网址为必填项,该网址可以通过观察 PaddleLabel-ML 启动时的命令行输出确定
34 | 
35 | 3. 模型和权重文件路径为选填项,如果留空,默认使用的模型是 HRNet18_OCR64 通用分割场景高精度模型。此外 EdgeFlow 还提供针对人像,遥感,医疗和瑕疵检测的垂类模型,您可以展开下方列表查看和下载。注意两个路径需要使用绝对路径,模型和权重文件要对应。
36 | 点击查看更多模型
37 |
38 | | 模型类型 | 适用场景 | 模型结构 | 模型下载地址 |
39 | | ------------ | -------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
40 | | 高精度模型 | 通用场景的图像标注 | HRNet18_OCR64 | [static_hrnet18_ocr64_cocolvis](https://paddleseg.bj.bcebos.com/eiseg/0.4/static_hrnet18_ocr64_cocolvis.zip) |
41 | | 轻量化模型 | 通用场景的图像标注 | HRNet18s_OCR48 | [static_hrnet18s_ocr48_cocolvis](https://paddleseg.bj.bcebos.com/eiseg/0.4/static_hrnet18s_ocr48_cocolvis.zip) |
42 | | 高精度模型 | 通用图像标注场景 | EdgeFlow | [static_edgeflow_cocolvis](https://paddleseg.bj.bcebos.com/eiseg/0.4/static_edgeflow_cocolvis.zip) |
43 | | 高精度模型 | 人像标注场景 | HRNet18_OCR64 | [static_hrnet18_ocr64_human](https://paddleseg.bj.bcebos.com/eiseg/0.4/static_hrnet18_ocr64_human.zip) |
44 | | 轻量化模型 | 人像标注场景 | HRNet18s_OCR48 | [static_hrnet18s_ocr48_human](https://paddleseg.bj.bcebos.com/eiseg/0.4/static_hrnet18s_ocr48_human.zip) |
45 | | 轻量化模型 | 遥感建筑物标注场景 | HRNet18s_OCR48 | [static_hrnet18_ocr48_rsbuilding_instance](https://paddleseg.bj.bcebos.com/eiseg/0.4/static_hrnet18_ocr48_rsbuilding_instance.zip) |
46 | | 高精度模型\* | x 光胸腔标注场景 | Resnet50_Deeplabv3+ | [static_resnet50_deeplab_chest_xray](https://paddleseg.bj.bcebos.com/eiseg/0.5/static_resnet50_deeplab_chest_xray.zip) |
47 | | 轻量化模型 | 医疗肝脏标注场景 | HRNet18s_OCR48 | [static_hrnet18s_ocr48_lits](https://paddleseg.bj.bcebos.com/eiseg/0.4/static_hrnet18s_ocr48_lits.zip) |
48 | | 轻量化模型\* | MRI 椎骨图像标注场景 | HRNet18s_OCR48 | [static_hrnet18s_ocr48_MRSpineSeg](https://paddleseg.bj.bcebos.com/eiseg/0.5/static_hrnet18s_ocr48_MRSpineSeg.zip) |
49 | | 轻量化模型\* | 质检铝板瑕疵标注场景 | HRNet18s_OCR48 | [static_hrnet18s_ocr48_aluminium](https://paddleseg.bj.bcebos.com/eiseg/0.5/static_hrnet18s_ocr48_aluminium.zip) |
50 |
51 |
52 |
53 | 4. 完成设置后点击“确定”,模型会在后台加载,通常时间不超过 1 分钟。加载完成后页面顶部会弹出消息`模型加载完成,您可以开始使用智能标注工具了`。
54 |
55 | ## 使用交互式标注
56 |
57 | 1. 点击页面右侧工具栏中“交互式分割”按钮进入交互式分割模式。此时页面上一些工具会被置灰禁用,再次点击“交互式分割”按钮退出后会恢复
58 | 
59 | 2. 选中一个标签,之后在图像中前景位置鼠标左键点击添加正样本点;在模型过度分割,掩膜蔓延到背景的位置鼠标右键点击添加负样本点,点击可以进行多轮。此外您可以在此过程中通过调整分割阈值控制整体边缘位置
60 | 3. 无论语义还是实例分割项目,推荐每次只用交互式分割标注一个对象,这样标注精度更高。完成一个对象的标注后,按下鼠标中键保存结果和清空当前控制点
61 |
--------------------------------------------------------------------------------
/doc/CN/ML/ml.md:
--------------------------------------------------------------------------------
1 | # 机器学习辅助标注
2 |
--------------------------------------------------------------------------------
/doc/CN/_config.yml:
--------------------------------------------------------------------------------
1 | title: PaddleLabel
2 | description: 高效灵活的数据标注工具
3 | theme: just-the-docs
4 |
5 | url: https://paddlecv-sig.github.io/
6 | baseurl: "/PaddleLabel/CN"
7 |
8 | permalink: pretty
9 |
10 | search_enabled: false
11 | heading_anchors: true
12 | enable_copy_code_button: true
13 |
14 | # footer
15 | last_edit_timestamp: true # show or hide edit time - page must have `last_modified_date` defined in the frontmatter
16 | last_edit_time_format: "%F %I:%M %p" # uses ruby's time format: https://ruby-doc.org/stdlib-2.7.0/libdoc/time/rdoc/Time.html
17 |
18 | # "%b %e %Y at %I:%M %p" Jan 1 2020 at 12:00 AM
19 | # "%Y-%m-%e %I:%M %p"
20 |
21 | gh_edit_link: true
22 | gh_edit_link_text: "在 Github 上编辑此页面"
23 | gh_edit_repository: "https://github.com/PaddleCV-SIG/PaddleLabel"
24 | gh_edit_branch: "develop"
25 | gh_edit_source: "doc/CN"
26 | gh_edit_view_mode: "edit"
27 | footer_content: "PaddleLabel 以 Apache 2.0 协议发行。本网站未引入任何访问统计"
28 |
29 | callouts:
30 | note:
31 | title: ""
32 | color: yellow
33 |
34 | aux_links: # remove if you don't want this link to appear on your pages
35 | 项目 Github: https://github.com/PaddleCV-SIG/PaddleLabel
36 |
37 | kramdown:
38 | parse_block_html: true
39 | # syntax_highlighter_opts:
40 | # block:
41 | # line_numbers: true
42 |
43 | # safe: false
44 |
45 | plugins:
46 | - jemoji
47 | - jekyll-assets
48 |
--------------------------------------------------------------------------------
/doc/CN/assets/accept_model_label.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/accept_model_label.png
--------------------------------------------------------------------------------
/doc/CN/assets/action-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/action-1.png
--------------------------------------------------------------------------------
/doc/CN/assets/add_label.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/add_label.png
--------------------------------------------------------------------------------
/doc/CN/assets/auto_inference.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/auto_inference.png
--------------------------------------------------------------------------------
/doc/CN/assets/classification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/classification.png
--------------------------------------------------------------------------------
/doc/CN/assets/cn_home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/cn_home.png
--------------------------------------------------------------------------------
/doc/CN/assets/create.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/create.png
--------------------------------------------------------------------------------
/doc/CN/assets/dataset_path.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/dataset_path.png
--------------------------------------------------------------------------------
/doc/CN/assets/dataset_split.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/dataset_split.png
--------------------------------------------------------------------------------
/doc/CN/assets/dont_accept_model_label.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/dont_accept_model_label.png
--------------------------------------------------------------------------------
/doc/CN/assets/export.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/export.png
--------------------------------------------------------------------------------
/doc/CN/assets/export_detail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/export_detail.png
--------------------------------------------------------------------------------
/doc/CN/assets/group_qr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/group_qr.png
--------------------------------------------------------------------------------
/doc/CN/assets/import_name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/import_name.png
--------------------------------------------------------------------------------
/doc/CN/assets/interact_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/interact_button.png
--------------------------------------------------------------------------------
/doc/CN/assets/interact_mode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/interact_mode.png
--------------------------------------------------------------------------------
/doc/CN/assets/interact_setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/interact_setting.png
--------------------------------------------------------------------------------
/doc/CN/assets/label_page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/label_page.png
--------------------------------------------------------------------------------
/doc/CN/assets/miniconda_cn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/miniconda_cn.png
--------------------------------------------------------------------------------
/doc/CN/assets/miniconda_init_cn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/miniconda_init_cn.png
--------------------------------------------------------------------------------
/doc/CN/assets/miniconda_install_type.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/miniconda_install_type.png
--------------------------------------------------------------------------------
/doc/CN/assets/ml_backend_url.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/ml_backend_url.png
--------------------------------------------------------------------------------
/doc/CN/assets/msvc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/msvc.png
--------------------------------------------------------------------------------
/doc/CN/assets/project_overview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/project_overview.png
--------------------------------------------------------------------------------
/doc/CN/assets/project_overview_to_label.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/project_overview_to_label.png
--------------------------------------------------------------------------------
/doc/CN/assets/project_overview_to_split.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/project_overview_to_split.png
--------------------------------------------------------------------------------
/doc/CN/assets/sample_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/sample_button.png
--------------------------------------------------------------------------------
/doc/CN/assets/sample_page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/sample_page.png
--------------------------------------------------------------------------------
/doc/CN/assets/sample_structure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/sample_structure.png
--------------------------------------------------------------------------------
/doc/CN/assets/start_two.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/start_two.png
--------------------------------------------------------------------------------
/doc/CN/assets/test_label.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/test_label.png
--------------------------------------------------------------------------------
/doc/CN/assets/to_auto_inference.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/to_auto_inference.png
--------------------------------------------------------------------------------
/doc/CN/assets/to_home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/to_home.png
--------------------------------------------------------------------------------
/doc/CN/assets/to_overview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/doc/CN/assets/to_overview.png
--------------------------------------------------------------------------------
/doc/CN/manual/classification.md:
--------------------------------------------------------------------------------
1 | # 图像分类手动标注
2 |
3 |
4 |
5 | - [单分类数据集格式](#%E5%8D%95%E5%88%86%E7%B1%BB%E6%95%B0%E6%8D%AE%E9%9B%86%E6%A0%BC%E5%BC%8F)
6 | - [ImageNet](#imagenet)
7 | - [ImageNet-txt](#imagenet-txt)
8 | - [多分类数据集格式](#%E5%A4%9A%E5%88%86%E7%B1%BB%E6%95%B0%E6%8D%AE%E9%9B%86%E6%A0%BC%E5%BC%8F)
9 | - [ImageNet-txt](#imagenet-txt)
10 | - [数据标注](#%E6%95%B0%E6%8D%AE%E6%A0%87%E6%B3%A8)
11 | - [下一步](#%E4%B8%8B%E4%B8%80%E6%AD%A5)
12 |
13 |
14 |
15 | {: .note }
16 | 有关数据集[导入](../quick_start.html#导入数据集),[导出](../quick_start.html#导出数据集),[训练/验证/测试集划分](../quick_start.html#数据集划分)步骤请参快速开始文档
17 |
18 | 
19 |
20 | PaddleLabel 支持**单分类**和**多分类**两种图像分类项目。其中单分类项目一张图片只能对应一个类别,多分类项目一张图片可以对应多个类别。
21 |
22 | ## 单分类数据集格式
23 |
24 | ### ImageNet
25 |
26 | v0.1.0+ {: .label }
27 |
28 | ImageNet 格式数据集中,图像所在文件夹名称即为图像类别。
29 |
30 | 样例格式如下,标注 `# 可选` 的文件导入时可以不提供:
31 |
32 | ```shell
33 | 数据集路径
34 | ├── Cat
35 | │ ├── cat-1.jpg
36 | │ ├── cat-2.png
37 | │ ├── cat-3.webp
38 | │ └── ...
39 | ├── Dog
40 | │ ├── dog-1.jpg
41 | │ ├── dog-2.jpg
42 | │ ├── dog-3.jpg
43 | │ └── ...
44 | ├── monkey.jpg
45 | ├── train_list.txt # 可选
46 | ├── val_list.txt # 可选
47 | ├── test_list.txt # 可选
48 | └── labels.txt # 可选
49 |
50 | # labels.txt
51 | Monkey
52 | Mouse
53 | Cat
54 |
55 | # train_list.txt
56 | Cat/cat-1.jpg 2
57 | ```
58 |
59 | 根据文件夹名表示类别的规则,上述数据集导入后,三张猫和三张狗的图片会有分类,monkey.jpg 没有分类。
60 |
61 | 如果提供了 labels.txt 文件,该文件中的类别会在开始导入图像之前按顺序创建。此后如果文件夹名表示的类别不存在也会自动创建,因此 labels.txt 不需要包含所有文件夹名。
62 |
63 | {: .note}
64 | ImageNet 格式仅以图像所在文件夹判断图像分类,train/val/test_list.txt 文件中的**子集划分信息会被导入**,但是其中的**类别信息不会被导入**。如果您数据集的类别信息保存在三个列表文件中,请使用 ImageNet-txt 格式
65 |
66 | ### ImageNet-txt
67 |
68 | v1.0.0+ {: .label }
69 |
70 | ImageNet-txt 格式的数据集在 train/val/test_list.txt 文件中记录图像的类别。
71 |
72 | 样例格式如下:
73 |
74 | ```shell
75 | 数据集路径
76 | ├── image
77 | │ ├── cat-1.jpg
78 | │ ├── cat-2.png
79 | │ ├── cat-3.webp
80 | │ ├── dog-1.jpg
81 | │ ├── dog-2.jpg
82 | │ ├── dog-3.jpg
83 | │ ├── monkey.jpg
84 | │ └── ...
85 | ├── train_list.txt # 可选
86 | ├── val_list.txt # 可选
87 | ├── test_list.txt # 可选
88 | └── labels.txt # 可选
89 |
90 | # labels.txt
91 | Monkey
92 | Mouse
93 | Cat
94 |
95 | # train_list.txt
96 | image/dog-1.jpg Dog
97 | image/cat-2.png 2 # 对应 labels.txt 中第三行类别 Cat
98 | ```
99 |
100 | labels.txt 的处理同 ImageNet 格式。在三个列表文件中,每行使用空格分隔,第一部分为到一个图片文件的路径,第二部分为一个字符串或一个数字代表类别。
101 |
102 | - labels.txt 中类别编号从 0 开始,所以数字类别 i 将对应 labels.txt 中第 i+1 行
103 | - 字符串类别的处理同 ImageNet 格式中的文件夹名,如果不存在对应类别将在导入过程中自动创建
104 |
105 | {: .note}
106 | 三个列表文件以空格为分隔符,请不要在文件路径或类别名称中使用空格
107 |
108 | ## 多分类数据集格式
109 |
110 | ### ImageNet-txt
111 |
112 | v0.1.0+ {: .label }
113 |
114 | 多分类的 ImageNet-txt 格式和单分类的基本相同,唯一区别是多分类的三个列表文件中,每行文件名后面可以跟多个空格分隔的表示类别的数字或字符串。
115 |
116 | 样例格式如下:
117 |
118 | ```shell
119 | 数据集路径
120 | ├── image
121 | │ ├── cat.jpg
122 | │ ├── dog.jpg
123 | │ └── monkey.jpg
124 | ├── labels.txt # 可选
125 | ├── test_list.txt # 可选
126 | ├── train_list.txt # 可选
127 | └── val_list.txt # 可选
128 |
129 | # labels.txt
130 | cat
131 | dog
132 | yellow
133 | black
134 |
135 | # train_list.txt
136 | image/cat.jpg 0 2 # 对应第一行和第3行类别,cat,yellow
137 | image/dog.jpg 1 3
138 | image/monkey.jpg monkey yellow black
139 | ```
140 |
141 | {: .note}
142 | 三个列表文件以空格为分隔符,请不要在文件路径或类别名称中使用空格
143 |
144 | ## 数据标注
145 |
146 | 创建项目后会自动跳转到标注页面
147 |
148 | 1. 您可以点击右侧类别列表下方“添加类别”按钮创建一个新类别
149 | 
150 | 
151 | 2. 您可以点击一个类别右侧的 x 删除该类别。注:如果有图片属于该类别,该类别不能被删除
152 | 3. 点击类别进行标注,单分类项目仅允许选中一个类别,多分类项目可以同时选中多个类别。每次选择后标注结果将自动保存,页面上方将提示“保存成功”
153 | 4. 完成一张图片标注后点击画布左右 < > 按钮切换图片
154 |
155 |
156 |
157 | ## 下一步
158 |
159 | 您可以继续浏览[自动预标注使用方法](/doc/CN/ML/auto_inference.md)了解如何使用 PaddleLabel-ML 提高分类项目标注效率。
160 |
--------------------------------------------------------------------------------
/doc/CN/manual/common.md:
--------------------------------------------------------------------------------
1 | ## 无标注数据集
2 |
3 | 如果您的数据集不包含任何标注,只需将所有图像文件放在一个文件夹下。 PaddleLabel 会遍历文件夹(及所有子文件夹)中所有文件,并按照**文件拓展名**判断其类型,导入所有图像文件。所有隐藏文件(文件名以`.`开头)将被忽略。
4 |
5 | ## 基础功能
6 |
7 | 不同类型项目的数据集文件结构有所不同,但大多数类型的项目都支持一些基础功能。
8 |
9 | ### labels.txt
10 |
11 | 所有不使用 COCO 格式保存标注的项目都支持`labels.txt`。PaddleLabel 在导入过程中会在数据集路径下寻找`labels.txt`文件。您可以在这个文件中列出该项目的所有标签(每行一个)。例如下面这样:
12 |
13 | ```text
14 | # labels.txt
15 | Monkey
16 | Mouse
17 | ```
18 |
19 | PaddleLabel 的标签名称支持任何字符串,但是标签名称可能被用作导出数据集的文件夹名,所以应避免任何您的操作系统不支持的字符串,可以参考[这篇回答](https://stackoverflow.com/a/31976060)。Paddle 生态中的其他工具对标签名可能有进一步限制,如[PaddleX](https://github.com/PaddlePaddle/PaddleX/blob/develop/docs/data/format/classification.md)不支持中文字符作为标签名称。
20 |
21 | 在导入过程中,`labels.txt`可以包含标签名以外的信息。目前支持 4 种格式,如下所示。其中`|`表示分隔符,默认为空格。
22 |
23 | 标签长度:
24 |
25 | - 1:标签名
26 | - 2:标签名 | 标签编号
27 | - 3:标签名 | 标签编号 | 十六进制颜色或常用颜色名称或灰度值
28 | - 5:标签名 | 标签编号 | 红色 | 绿色 | 蓝色
29 |
30 | 其他:
31 |
32 | - `//`:`//`后的字符串将被作为标签注释
33 | - `-`:如果需要指定标签颜色,但不想指定标签编号,在标签编号位置写`-`
34 |
35 | 一些例子:
36 |
37 | ```text
38 | dog
39 | monkey 4
40 | mouse - #0000ff // mouse's id will be 5
41 | cat 10 yellow
42 | zibra 11 blue // some common colors are supported
43 | snake 12 255 0 0 // rgb color
44 | ```
45 |
46 | 所有支持的颜色名称在[这里](https://github.com/PaddleCV-SIG/PaddleLabel/blob/develop/paddlelabel/task/util/color.py#L15)列出。
47 |
48 | 在导入过程中,PaddleLabel 会首先创建`labels.txt`中指定的标签。因此这个文件中的标签的编号将从**0**开始并递增。在导出过程中也将生成此文件。
49 |
50 | ### xx_list.txt
51 |
52 | 所有不使用 COCO 格式保存标注的项目都支持`xx_list.txt`。`xx_list.txt`包括`train_list.txt`,`val_list.txt`和`test_list.txt`。这三个文件需要放在数据集文件夹的根目录中,与`labels.txt`相同。
53 |
54 | 这三个文件指定了数据集的划分以及标签或标注文件与图像文件间的匹配关系(比如 voc 格式下,每一行是图像文件的路径和标签文件的路径)。这三个文件的内容结构相同,每一行都以一条数据的路径开始,其路径为相对数据集根目录的相对路径,后面跟着表示类别的整数/字符串,或者标签文件的路径。例如:
55 |
56 | ```text
57 | # train_list.txt
58 | image/9911.jpg 0 3
59 | image/9932.jpg 4
60 | image/9928.jpg Cat
61 | ```
62 |
63 | 或
64 |
65 | ```text
66 | # train_list.txt
67 | JPEGImages/1.jpeg Annotations/1.xml
68 | JPEGImages/2.jpeg Annotations/2.xml
69 | JPEGImages/3.jpeg Annotations/3.xml
70 | ```
71 |
72 | 需要注意的是,**大多数项目都只会用到`xx_list.txt`中的数据集划分信息**。
73 |
74 | 如果标签类别为整数,PaddleLabel 将在`labels.txt`中查找标签,标签 id 从**0**开始。一些数据集中一条数据可以有多个类别,比如图像多分类。如果希望用数字作为标签名称,您可以将数字写在`labels.txt`中,并在`xx_list.txt`中提供标签 id。或者可以给数字标签加一个前缀,例如将`10`表示为`n10`。
75 |
76 | 这三个文件都将在导出过程中生成,即使其中一些文件是空的。注意,为了确保这些文件可以被 Paddle 生态系统中的其他工具读取,没有注释的数据**不会包含在`xx_list.txt`中**。
77 |
--------------------------------------------------------------------------------
/doc/CN/manual/instance_segmentation.md:
--------------------------------------------------------------------------------
1 | # 实例分割手动标注
2 |
3 |
4 |
5 | - [数据结构](#%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84)
6 | - [掩膜格式](#%E6%8E%A9%E8%86%9C%E6%A0%BC%E5%BC%8F)
7 | - [多边形格式](#%E5%A4%9A%E8%BE%B9%E5%BD%A2%E6%A0%BC%E5%BC%8F)
8 | - [数据标注](#%E6%95%B0%E6%8D%AE%E6%A0%87%E6%B3%A8)
9 | - [多边形标注](#%E5%A4%9A%E8%BE%B9%E5%BD%A2%E6%A0%87%E6%B3%A8)
10 | - [掩膜标注](#%E6%8E%A9%E8%86%9C%E6%A0%87%E6%B3%A8)
11 | - [下一步](#%E4%B8%8B%E4%B8%80%E6%AD%A5)
12 |
13 |
14 |
15 | 
16 |
17 | {: .note }
18 | 有关数据集[导入](../quick_start.html#导入数据集),[导出](../quick_start.html#导出数据集),[训练/验证/测试集划分](../quick_start.html#数据集划分)步骤请参快速开始文档
19 |
20 | PaddleLabel 将语义分割和实例分割视为两种项目类型,目前二者之间不支持转换。在语义分割项目中,每个像素将有一个分类,表示其为背景或前景中的某一类别。实例分割项目在逐像素分类的基础上给每个像素一个实例 id,即不仅区分像素所属类别,而且区分同一类别下像素属于哪个实例。
21 |
22 | PaddleLabel 支持多种分割数据集格式,各种类型的数据集导入后都可以使用多边形和笔刷两种标注工具。数据集导出时
23 |
24 | - 如果导出掩膜格式,多边形标注会被转换成掩模格式
25 | - 如果导出多边形格式,会跳过所有掩膜格式标注
26 |
27 | ## 数据结构
28 |
29 | ### 掩膜格式
30 |
31 | {: .label }
32 | v0.1.0+
33 |
34 | 样例格式如下:
35 |
36 | ```shell
37 | 数据集路径
38 | ├── Annotations
39 | │ ├── A0001.tif
40 | │ ├── B0001.tif
41 | │ ├── H0002.tif
42 | │ └── ...
43 | ├── JPEGImages
44 | │ ├── A0001.jpg
45 | │ ├── B0001.png
46 | │ ├── H0002.bmp
47 | │ └── ...
48 | ├── labels.txt
49 | ├── test_list.txt
50 | ├── train_list.txt
51 | └── val_list.txt
52 |
53 | # labels.txt
54 | background -
55 | optic_disk - 128 0 0 // 对于伪彩色掩膜,需要按此结构提供每个类别的颜色。灰度掩膜的id默认为从0开始依次递增
56 | ```
57 |
58 | ### 多边形格式
59 |
60 | {: .label }
61 | v0.1.0+
62 |
63 | 样例格式如下:
64 |
65 | ```shell
66 | 数据集路径
67 | ├── image
68 | │ ├── 0001.jpg
69 | │ ├── 0002.jpg
70 | │ ├── 0003.jpg
71 | │ └── ...
72 | ├── train.json
73 | ├── val.json
74 | └── test.json
75 | ```
76 |
77 | COCO 文件的格式如下:
78 |
79 | ```text
80 | {
81 | "info": info,
82 | "images": [image],
83 | "annotations": [annotation],
84 | "licenses": [license],
85 | "categories": [category],
86 | }
87 |
88 | image{
89 | "id": int,
90 | "width": int,
91 | "height": int,
92 | "file_name": str,
93 | "license": int,
94 | "flickr_url": str,
95 | "coco_url": str,
96 | "date_captured": datetime,
97 | }
98 |
99 | annotation{
100 | "id": int,
101 | "image_id": int,
102 | "category_id": int,
103 | "segmentation": RLE or [polygon],
104 | "area": float,
105 | "bbox": [x,y,width,height],
106 | "iscrowd": 0 or 1,
107 | }
108 |
109 | category{
110 | "id": int,
111 | "name": str,
112 | "supercategory": str,
113 | "color": str // this feature is specific to PP Label. It's not in the coco spec.
114 | }
115 | ```
116 |
117 |
118 | ## 数据标注
119 |
120 | ### 多边形标注
121 |
122 | 1. 点击右侧“添加标签”,填写信息并创建标签
123 | 2. 选择一个标签,点击左侧工具栏的“多边形”,在图像界面上点击需要标注的物体轮廓,形成多边形包围物体,实例分割可以反复选择同一标签标注不同的实例,需要修改多边形可以点击左侧工具栏的“编辑”进行修改
124 | 3. **标注完成一个实例后,点击右上角"确定轮廓"进行实例确认**
125 | 4. 点击左右按钮切换图像,重复上述操作,直到所有数据标注完毕
126 | 5. 下方进度展示可以查看标注进度
127 |
128 | ### 掩膜标注
129 |
130 | 1. 点击右侧“添加标签”,填写信息并创建标签
131 | 2. 选择一个标签,点击左侧工具栏的“笔刷”(鼠标悬浮可以修改笔刷大小),在图像界面上按住鼠标左键绘制需要标注的物体内部,实例分割可以反复选择同一标签标注不同的实例,,需要删除掩膜可以点击左侧工具栏的“橡皮擦”进行修改
132 | 3. **标注完成一个实例后,点击右上角"确定轮廓"进行实例确认**
133 | 4. 点击左右按钮切换图像,重复上述操作,直到所有数据标注完毕
134 | 5. 下方进度展示可以查看标注进度
135 |
136 |
137 |
138 | ## 下一步
139 |
140 | 您可以继续浏览[交互式分割使用方法](/doc/CN/ML/interactive_segmentation.md)了解如何使用 PaddleLabel-ML 提高语义分割标注效率。
141 |
--------------------------------------------------------------------------------
/doc/CN/manual/manual.md:
--------------------------------------------------------------------------------
1 | # 手动标注
2 |
3 | {: toc}
4 |
--------------------------------------------------------------------------------
/doc/CN/manual/ocr.md:
--------------------------------------------------------------------------------
1 | # OCR 手动标注
2 |
3 |
4 |
5 | - [数据集格式](#%E6%95%B0%E6%8D%AE%E9%9B%86%E6%A0%BC%E5%BC%8F)
6 | - [PaddleOCR txt](#paddleocr-txt)
7 | - [数据标注](#%E6%95%B0%E6%8D%AE%E6%A0%87%E6%B3%A8)
8 | - [两点矩形](#%E4%B8%A4%E7%82%B9%E7%9F%A9%E5%BD%A2)
9 | - [多边形](#%E5%A4%9A%E8%BE%B9%E5%BD%A2)
10 | - [下一步](#%E4%B8%8B%E4%B8%80%E6%AD%A5)
11 |
12 |
13 |
14 | {: .note }
15 | 有关数据集[导入](../quick_start.html#导入数据集),[导出](../quick_start.html#导出数据集),[训练/验证/测试集划分](../quick_start.html#数据集划分)步骤请参快速开始文档
16 |
17 | PaddleLabel 目前支持 PaddleOCR txt 格式的数据集导入导出。
18 |
19 | ## 数据集格式
20 |
21 | ### PaddleOCR txt
22 |
23 | {: .label } v1.0.0+
24 |
25 | PaddleOCR txt 格式中,所有标注数据存储在 Label.txt 文件中。
26 |
27 | 样例格式如下:
28 |
29 | ```shell
30 | 数据集路径
31 | ├── image
32 | │ ├── 1.jpg
33 | │ ├── 2.png
34 | │ ├── 3.webp
35 | │ └── ...
36 | └── Label.txt # 可选
37 |
38 | # Label.txt
39 | 05.jpg [{"points": [[x1, y1], [x2, y2], [x3, y3], [x4, y4]], "transcription": "文字内容", "illegibility": true, "language": "ch"}, ...]
40 | ```
41 |
42 | ## 数据标注
43 |
44 | PaddleLabel 目前支持两顶点矩形和多边形两种文字位置标画工具。完成文字位置标画后,右侧“识别结果”列表中会添加一条记录,文字内容为“待识别”。单击一条识别结果中的文字可以对其进行编辑。
45 |
46 | ### 两点矩形
47 |
48 | 两点矩形的四条边为水平或竖直方向,仅支持对矩形四个顶点中两个的位置进行修改。如果需要四点的自由四边形,请使用多边形工具。创建两点矩形识别记录的过程如下
49 |
50 | 1. 在左侧工具栏中点击激活“矩形”工具
51 | 2. 在画布中按住鼠标左键进行拖拽创建一个矩形。松开左键后标注记录会自动保存
52 | 3. 在右侧识别结果列表中修改识别记录文字内容
53 |
54 | ### 多边形
55 |
56 | 多边形识别记录的所有顶点位置都可以修改,使用过程如下
57 |
58 | 1. 在左侧工具栏中点击激活“多边形”工具
59 | 2. 围绕文字区域,点击鼠标左键添加多边形顶点标画文字位置。完成标画后点击鼠标右键。多边形记录会自动保存
60 | 3. 在右侧识别结果列表中修改识别记录文字内容
61 |
62 | ## 下一步
63 |
64 | 您可以继续浏览[自动预标注使用方法](/doc/CN/ML/auto_inference.md)了解如何使用 PaddleLabel-ML 提高 OCR 项目标注效率。
65 |
--------------------------------------------------------------------------------
/doc/CN/manual/semantic_segmentation.md:
--------------------------------------------------------------------------------
1 | # 语义分割手动标注
2 |
3 |
4 |
5 | - [数据结构](#%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84)
6 | - [掩膜格式](#%E6%8E%A9%E8%86%9C%E6%A0%BC%E5%BC%8F)
7 | - [COCO 格式](#coco-%E6%A0%BC%E5%BC%8F)
8 | - [数据标注](#%E6%95%B0%E6%8D%AE%E6%A0%87%E6%B3%A8)
9 | - [多边形标注](#%E5%A4%9A%E8%BE%B9%E5%BD%A2%E6%A0%87%E6%B3%A8)
10 | - [掩膜标注](#%E6%8E%A9%E8%86%9C%E6%A0%87%E6%B3%A8)
11 | - [下一步](#%E4%B8%8B%E4%B8%80%E6%AD%A5)
12 |
13 |
14 |
15 | {: .note }
16 | 有关数据集[导入](../quick_start.html#导入数据集),[导出](../quick_start.html#导出数据集),[训练/验证/测试集划分](../quick_start.html#数据集划分)步骤请参快速开始文档
17 |
18 | 
19 |
20 | PaddleLabel 将语义分割和实例分割视为两种项目类型,目前二者之间不支持转换。在语义分割项目中,每个像素有一个分类,表示其为背景或前景中的某一类别。实例分割项目在逐像素分类的基础上给每个像素一个实例 id,即不仅区分像素所属类别,而且区分同一类别下像素属于哪个实例。
21 |
22 | PaddleLabel 支持多种分割数据集格式,各种类型的数据集导入后都可以使用多边形和笔刷两种标注工具。数据集导出时
23 |
24 | - 如果导出掩膜格式,多边形标注会被转换成掩模格式
25 | - 如果导出多边形格式,会跳过所有掩膜格式标注
26 |
27 | ## 数据结构
28 |
29 | ### 掩膜格式
30 |
31 | {: .label } v0.1.0+
32 |
33 | 掩膜格式数据集中图片和掩膜一般都是图片文件,二者需要通过所在文件夹进行区分。**创建此类型标注项目时,请将待标注图片放在`JPEGImages`文件夹中,将已有标注放在`Annotations`文件夹中,数据集路径请填写二者的上层目录(下方示例中的`数据集路径`)。**
34 |
35 | {: .note}
36 | 此类型项目可以导入 EISeg 保存的灰度和伪彩色掩膜。不过 EISeg 保存伪彩色掩膜时文件名格式为 `图片名_pseudo.png` ,导入前需要去掉伪彩色掩膜文件名中的`_pseudo`部分,重命名为 `图片名.png`。
37 |
38 | 样例格式如下:
39 |
40 | ```shell
41 | 数据集路径
42 | ├── Annotations
43 | │ ├── A0001.png
44 | │ ├── B0001.png
45 | │ ├── H0002.png
46 | │ └── ...
47 | ├── JPEGImages
48 | │ ├── A0001.jpg
49 | │ ├── B0001.png
50 | │ ├── H0002.bmp
51 | │ └── ...
52 | ├── labels.txt
53 | ├── test_list.txt
54 | ├── train_list.txt
55 | └── val_list.txt
56 |
57 | # labels.txt
58 | background
59 | optic_disk - 128 0 0 // 对于伪彩色掩膜,需要按此结构提供每个类别的颜色。灰度掩膜的id默认为从0开始依次递增
60 | ```
61 |
62 |
63 |
64 | ### COCO 格式
65 |
66 | {: .label } v0.1.0+
67 |
68 | COCO 格式的图片和标注对应规则可以参考[检测项目](./detection.md#coco)中的描述。
69 |
70 | 样例格式如下:
71 |
72 | ```shell
73 | 数据集路径
74 | ├── image
75 | │ ├── 0001.jpg
76 | │ ├── 0002.jpg
77 | │ ├── 0003.jpg
78 | │ └── ...
79 | ├── train.json
80 | ├── val.json
81 | └── test.json
82 | ```
83 |
84 | COCO 文件的格式如下:
85 |
86 | ```text
87 | {
88 | "info": info,
89 | "images": [image],
90 | "annotations": [annotation],
91 | "licenses": [license],
92 | "categories": [category],
93 | }
94 |
95 | image{
96 | "id": int,
97 | "width": int,
98 | "height": int,
99 | "file_name": str,
100 | "license": int,
101 | "flickr_url": str,
102 | "coco_url": str,
103 | "date_captured": datetime,
104 | }
105 |
106 | annotation{
107 | "id": int,
108 | "image_id": int,
109 | "category_id": int,
110 | "segmentation": RLE or [polygon],
111 | "area": float,
112 | "bbox": [x,y,width,height],
113 | "iscrowd": 0 or 1,
114 | }
115 |
116 | category{
117 | "id": int,
118 | "name": str,
119 | "supercategory": str,
120 | "color": str // this feature is specific to PP Label. It's not in the coco spec.
121 | }
122 | ```
123 |
124 | ## 数据标注
125 |
126 | 语义分割项目支持多边形和笔刷/橡皮掩膜标注两种标画工具
127 |
128 | ### 多边形标注
129 |
130 | 1. 在右侧“类别列表”中点击选中一个类别,在左侧工具栏中点击“多边形”按钮激活该工具
131 | 2. 在图像中沿待标注物体的边缘点击,使用多边形包围该物体。完成后`点击鼠标右键结束对该物体的标注`,标注结果将自动保存。这一过程可以重复多次,通常一个多边形只框选一个物体
132 | 3. 如需要修改多边形顶点可以在左侧工具栏中点击“编辑”,之后拖动顶点位置
133 | 4. 完成一张图片标注后点击画布两侧的 < > 按钮切换图片
134 |
135 | ### 掩膜标注
136 |
137 | 1. 在右侧“类别列表”中点击选中一个类别,在左侧工具栏中点击“笔刷”按钮激活该工具
138 | 2. 鼠标悬浮在笔刷工具上方时,可以在弹出的悬浮框中调整笔刷大小
139 | 3. 在图像中使用笔刷标画所有属于该类别的像素。可以使用橡皮擦工具擦除过多的标画。每笔标注会自动保存
140 | 4. 完成一张图片标画后点击画布两侧 < > 按钮切换图片
141 |
142 | ## 下一步
143 |
144 | 您可以继续浏览[交互式分割使用方法](/doc/CN/ML/interactive_segmentation.md)了解如何使用 PaddleLabel-ML 提高语义分割标注效率
145 |
--------------------------------------------------------------------------------
/doc/CN/release_notes.md:
--------------------------------------------------------------------------------
1 | # PaddleLabel 版本更新记录
2 |
3 |
4 |
5 | - [v1.0.1 2023-01-27](#v101-2023-01-27)
6 | - [v1.0.0 2023-01-17](#v100-2023-01-17)
7 | - [v0.5.0 2022-11-30](#v050-2022-11-30)
8 | - [v0.1.0 2022-08-18](#v010-2022-08-18)
9 |
10 |
11 |
12 |
16 |
17 |
18 |
19 | ## v1.0.1 2023-01-27
20 |
21 | - 前端
22 | - 【目标检测】:修复 自动推理添加结果类型为 ocr 矩形的问题
23 | - 【自动推理】:改善 为各个类型项目设置较为合理的默认自动推理阈值
24 | - 后端
25 | - 【更新提示】:改善 在检测到更新时指引用户访问本页面查看更新内容
26 | - 【windows 中文路径】:改善 全面从 cv2.imread 转向 PIL.Image.open,取得更好的中文路径支持
27 | - 【样例数据集】:改善 备份旧版样例数据集并重新创建,去除一些旧版中的文件
28 | - 【目标检测】:修复 coco 格式导出长宽翻转错误
29 |
30 |
31 |
32 | ## v1.0.0 2023-01-17
33 |
34 | - 【OCR】新增 OCR 项目标注能力,支持 [PP-OCRv3](https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.6/doc/doc_ch/PP-OCRv3_introduction.md) 模型预标注
35 | - 【导入/导出】新增 EISeg 格式导入,新增大量[自动化测试](https://github.com/PaddleCV-SIG/PaddleLabel/actions/workflows/cypress.yml),修复诸多导入导出 bug
36 | - 【文档】重新梳理后[文档](https://paddlecv-sig.github.io/PaddleLabel/)内容简洁清晰并和软件一同打包发布,进一步降低上手难度
37 |
38 |
39 |
40 | ## v0.5.0 2022-11-30
41 |
42 | - 【界面】全面升级分类、检测及分割的前端标注界面体验,显著提升标注流畅度
43 | - 【分类】新增 PPLCNet 预训练模型,为分类功能提供预标注能力
44 | - 【检测】新增 PicoDet 预训练模型,为检测功能提供预标注能力
45 | - 【分割】(1)优化语义分割及实例分割关于实例的区分,实例分割通过'确认轮廓'来区分实例; (2)新增根据类别或根据实例选择颜色显示模式; (3)修复交互式分割 localStorage 超限问题
46 |
47 |
48 |
49 | ## v0.1.0 2022-08-18
50 |
51 | - 【分类】支持单分类与多分类标注及标签的导入导出。简单灵活实现自定义数据集分类标注任务并导出供[PaddleClas](https://github.com/PaddlePaddle/PaddleClas)进行训练
52 | - 【检测】支持检测框标注及标签的导入导出。快速上手生成自己的检测数据集并应用到[PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection)
53 | - 【分割】支持多边形、笔刷及交互式等多种标注方式,支持标注语义分割与实例分割两种场景。多种分割标注方式可灵活选择,方便将导出数据应用在[PaddleSeg](https://github.com/PaddlePaddle/PaddleSeg)获取个性化定制模型
54 |
--------------------------------------------------------------------------------
/doc/CN/training/PdLabel_PdDet.md:
--------------------------------------------------------------------------------
1 | # 道路标志检测:从 PaddleLabel 到 PaddleDetection
2 |
3 | PaddleLabel 标注数据+PaddleDetection 训练预测=快速完成一次目标检测的任务
4 |
5 | ______________________________________________________________________
6 |
7 | ## 1. 数据准备
8 |
9 | - 首先使用`PaddleLabel`对自制的路标数据集进行标注,其次使用`Split Dataset`功能分割数据集,最后导出数据集
10 | - 从`PaddleLabel`导出后的内容全部放到自己的建立的文件夹下,例如`roadsign_det_dataset`,其目录结构如下:
11 |
12 | ```
13 | ├── roadsign_det_dataset
14 | │ ├── Annotations
15 | │ ├── JPEGImages
16 | │ ├── labels.txt
17 | │ ├── test_list.txt
18 | │ ├── train_list.txt
19 | │ ├── val_list.txt
20 | ```
21 |
22 | ## 2. 训练
23 |
24 | ### 2.1 安装必备的库
25 |
26 | **2.1.1 安装 paddlepaddle**
27 |
28 | ```
29 | # 您的机器安装的是 CUDA9 或 CUDA10,请运行以下命令安装
30 | pip install paddlepaddle-gpu -i https://mirror.baidu.com/pypi/simple
31 | # 您的机器是CPU,请运行以下命令安装
32 | # pip install paddlepaddle
33 | ```
34 |
35 | **2.1.2 安装 paddledetection 以及依赖项**
36 |
37 | ```
38 | git clone https://gitee.com/paddlepaddle/PaddleDetection
39 | cd PaddleDetection
40 | pip install -r requirements.txt
41 | python setup.py install
42 | ```
43 |
44 | ### 2.2 准备自制的路标数据集
45 |
46 | ```
47 | cd ./PaddleDection/dataset/
48 | mkdir roadsign_det_dataset
49 | cd ../../
50 | cp -r ./roadsign_det_dataset/* ./PaddleDection/dataset/roadsign_det_dataset
51 | ```
52 |
53 | ### 2.3 修改配置文件
54 |
55 | 该任务主要涉及 6 个配置文件,分别是:
56 |
57 | 1. 主配置文件入口:yolov3_mobilenet_v1_roadsign.yml
58 | 1. 定义训练数据的路径:roadsign_voc.yml
59 | 1. 定义公共参数:runtime.yml
60 | 1. 定义优化器的策略:optimizer_40e.yml
61 | 1. 定义模型和主干网络:yolov3_mobilenet_v1.yml
62 | 1. 定义数据预处理方式:yolov3_reader.yml
63 |
64 | 这里我们只需要改动一个配置文件即定义训练数据的路径的配置文件:
65 |
66 | > PaddleDetection/configs/datasets/roadsign_voc.yml
67 |
68 | ```
69 | metric: VOC
70 | map_type: integral
71 | num_classes: 4
72 |
73 | TrainDataset:
74 | !VOCDataSet
75 | dataset_dir: dataset/roadsign_det_dataset
76 | anno_path: train_list.txt
77 | label_list: labels.txt
78 | data_fields: ['image', 'gt_bbox', 'gt_class', 'difficult']
79 |
80 | EvalDataset:
81 | !VOCDataSet
82 | dataset_dir: dataset/roadsign_det_dataset
83 | anno_path: val_list.txt
84 | label_list: labels.txt
85 | data_fields: ['image', 'gt_bbox', 'gt_class', 'difficult']
86 |
87 | TestDataset:
88 | !ImageFolder
89 | anno_path: dataset/roadsign_det_dataset/labels.txt
90 | ```
91 |
92 | ### 2.4 开始训练
93 |
94 | ```
95 | export CUDA_VISIBLE_DEVICES=0
96 | # 开始训练
97 | python PeddleDetection/tools/train.py -c configs/yolov3/yolov3_mobilenet_v1_roadsign.yml --eval -o use_gpu=true
98 | ```
99 |
100 | ## 3. 模型评估
101 |
102 | ### 3.1 评估
103 |
104 | ```
105 | python PeddleDetection/tools/eval.py -c PeddleDetection/configs/yolov3/yolov3_mobilenet_v1_roadsign.yml -o use_gpu=true
106 | ```
107 |
108 | ### 3.2 预测
109 |
110 | ```
111 | python PeddleDetection/tools/infer.py \
112 | -c PeddleDetection/configs/yolov3/yolov3_mobilenet_v1_roadsign.yml \
113 | -o use_gpu=true \
114 | --infer_img=demo/road554.png
115 | ```
116 |
117 | 预测的样例图片如下图:
118 |
119 |
120 |
121 | 预测的结果是:
122 |
123 | > speedlimit 0.77 预测正确 ✔
124 |
125 | ## AI Studio 第三方教程推荐
126 |
127 | [快速体验演示案例](https://aistudio.baidu.com/aistudio/projectdetail/4349280)
128 |
--------------------------------------------------------------------------------
/doc/CN/training/training.md:
--------------------------------------------------------------------------------
1 | # 进行训练
2 |
--------------------------------------------------------------------------------
/doc/EN/_config.yml:
--------------------------------------------------------------------------------
1 | title: PaddleLabel
2 | description: An effective and flexible tool for data annotation
3 | theme: just-the-docs
4 |
5 | url: https://paddlecv-sig.github.io/
6 | baseurl: "/PaddleLabel/EN/"
7 |
8 | permalink: pretty
9 |
10 | search_enabled: false
11 | heading_anchors: true
12 | enable_copy_code_button: true
13 |
14 | aux_links: # remove if you don't want this link to appear on your pages
15 | Project Github: https://github.com/PaddleCV-SIG/PaddleLabel/
16 |
17 | plugins:
18 | - jemoji
19 |
20 | kramdown:
21 | parse_block_html: true
22 | # syntax_highlighter_opts:
23 | # block:
24 | # line_numbers: true
25 |
--------------------------------------------------------------------------------
/doc/EN/assets/group_qr.png:
--------------------------------------------------------------------------------
1 | ../../CN/assets/group_qr.png
--------------------------------------------------------------------------------
/doc/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem "jekyll", "~> 4.3" # installed by `gem jekyll`
4 | # gem "webrick" # required when using Ruby >= 3 and Jekyll <= 4.2.2
5 |
6 | gem "just-the-docs", "0.4.0.rc4" # currently the latest pre-release
7 | # gem "just-the-docs" # the latest release - currently 0.3.3
8 |
9 | gem "jemoji"
10 | gem "jekyll-assets", group: :jekyll_plugins
11 |
--------------------------------------------------------------------------------
/doc/README.md:
--------------------------------------------------------------------------------
1 | CN/README.md
--------------------------------------------------------------------------------
/doc/old/detection_ml.md:
--------------------------------------------------------------------------------
1 | # 目标检测自动标注
2 |
3 |
4 | - [简介](#%E7%AE%80%E4%BB%8B)
5 | - [使用教程](#%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B)
6 | - [安装](#%E5%AE%89%E8%A3%85)
7 | - [使用](#%E4%BD%BF%E7%94%A8)
8 |
9 |
10 |
11 | {: note}
12 | 在使用辅助标注功能前请先按照 [此文档](/doc/CN/ML/install_ml.md) 介绍步骤安装并启动 PaddleLabel-ML 后端
13 | ## 简介
14 |
15 | PaddleLabel 提供图像检测自动标注功能,用户只需要在`自动推理设置`中进行简单设置,即可启用自动标注的功能,从而更快的完成对应的图像检测标注任务。
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | ## 使用教程
24 |
25 | ### 安装
26 |
27 | - 创建虚拟环境
28 |
29 | ```shell
30 | # 创建虚拟环境
31 | conda create -n paddlelabel python=3.10
32 | conda activate paddlelabel
33 | ```
34 |
35 | - 安装 PaddlePaddle
36 |
37 | 版本要求: PaddlePaddle >= 2.2.0
38 |
39 | PaddlePaddle 安装请参考[官网](https://www.paddlepaddle.org.cn/install/quick?docurl=/documentation/docs/zh/install/pip/windows-pip.html)。
40 |
41 | - 安装前端和机器学习后端
42 |
43 | ```shell
44 | pip install paddlelabel
45 | pip install paddlelabel_ml
46 | ```
47 |
48 | ### 使用
49 |
50 | 0. **启动**
51 |
52 | 可以直接打开两个终端,分别使用如下指令启动 PaddleLabel 的前后端。
53 |
54 | ```shell
55 | paddlelabel # 启动paddlelabel,前端
56 | ```
57 |
58 | ```shell
59 | paddlelabel_ml # 启动paddlelabel_ml,机器学习后端
60 | ```
61 |
62 | 1. **新项目创建**
63 |
64 | 浏览器打开 PaddleLabel 后,可以通过创建项目下的“图像检测”卡片创建一个新的图像检测标注项目(如果已经创建,可以通过下方“我的项目”找到对应名称的项目,点击“标注”继续标注)。
65 |
66 | 项目创建选项卡有如下选项需要填写:
67 |
68 | - 项目名称(必填):填写该检测标注项目的项目名
69 | - 数据地址(必填):填写本地数据集文件夹的路径,可以直接通过复制路径并粘贴得到。
70 | - 数据集描述(选填):填写该检测标注项目的使用的数据集的描述文字
71 | - 导入标注格式(必选):选择该任务导入标签为 COCO、VOC 或 YOLO 格式
72 |
73 | 对于标签格式的详细说明,请参考[目标检测标注](detection.html)。
74 |
75 | 1. **数据导入**
76 |
77 | 在创建项目时需要填写数据地址,该地址对应的是数据集的文件夹,为了使 PaddleLabel 能够正确的识别和处理数据集,请参考[数据结构](dataset_file_structure.html)组织数据集。同时 PaddleLabel 提供了参考数据集,位于`~/.paddlelabel/sample/det`路径下,也可参考该数据集文件结构组织数据。
78 |
79 | 3. **智能标注**
80 |
81 | 进入标注界面,在检测任务的标注中,除了手动标注外[(数据标注)](detection.html),还可以按照如下步骤进行智能标注,即使用图像检测模型来自动标注。
82 |
83 | 1. 点击右侧“项目总览”,进入项目总览界面
84 |
85 |
86 |
87 |
88 |
89 | 2. 点击“自动推理设置”,进入对应设置页面后,有如下选项需要填写:
90 |
91 |
92 |
93 |
94 |
95 | - 机器学习后端网址(必填):填写在终端中使用`paddlelabel_ml`命令启动后的机器学习后端网址,默认为`http://127.0.0.1:1234`。
96 |
97 | - 模型选择(必选):选择 PaddleLabel 支持的图像检测模型,目前可选模型有 PicoDet。
98 |
99 | - 使用预标注模型标签(必选):选择是否使用预标注模型便签,选择'是'则表示用户接受模型推理出的标签来作为图像检测的标注标签,接受预标注模型标签后,当模型检测到新标签后,会自动在标签列表中增加该标签;选择'否',则用户需要自行建立标签对应关系。
100 |
101 | - 标签对应关系(非必填):如果用户在`使用预标注模型标签`选项栏中选择'是',则`标签对应关系`处可不填,选择'否',此时`标签对应关系`处显示两个选择框,左侧的选择框中的标签为模型推理的标签,支持模糊搜索,右侧的选择框中的标签为标签列表中出现过的标签,用户也可以在此处新增标签,用户可按照自己的偏好建立标签对,这样就实现了模型推理标签和用户自定义标签的一一对应,从而就可以在图像检测智能标注中只展示符合用户自定义标签的结果。
102 |
103 | 最后选择`确定`按钮,即可完成"自动推理设置"
104 |
105 | 3. 点击"去标注",进入标注界面
106 |
107 | 1. 点击"自动推理",模型给出的预测结果即可显示到标签列表中,如果提示"自动推理未发现高置信度结果",则可点击"推理阈值",相应的调低推理阈值后再次点击"自动推理",即可得到预测结果
108 |
109 | 1. 如果对自动推理的结果不满意,用户可点击`清空标注`按钮以及`添加标签`按钮来为当前图像进行手动添加标签进行标注
110 |
111 | 1. 点击左右按钮切换图像,重复上述步骤 4 和步骤 5 操作,直到所有数据标注完毕
112 |
113 | 1. 下方进度展示可以查看标注进度
114 |
115 | 1. **完成标注**
116 |
117 | - 完成数据标注后,PaddleLabel 提供了方便的数据划分功能,以便与 Paddle 其他工具套件(如 PaddleDetection)进行快速衔接。点击右侧工具栏的**项目总览**按钮,来到该项目的总览界面,这里可以看到数据以及标注状态。
118 |
119 | - 点击**划分数据集**按钮弹出划分比例的设置,分别填入对应训练集、验证集和测试集的占比,点击确定即可完成数据集的划分。
120 |
121 | - 点击**导出数据集**,输入需要导出到的文件夹路径,点击确认,即可导出标注完成的数据到指定路径。
122 |
--------------------------------------------------------------------------------
/doc/prepare.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from pathlib import Path
3 | import sys
4 | import subprocess
5 |
6 | headers = {
7 | "CN/README.md": """---
8 | layout: home
9 | title: 项目简介
10 | nav_order: 0
11 | permalink: /
12 | """,
13 | "CN/install.md": """---
14 | layout: default
15 | title: 安装
16 | nav_order: 1
17 | """,
18 | "CN/quick_start.md": """---
19 | layout: default
20 | title: 快速体验
21 | nav_order: 2
22 | """,
23 | # 手动标注
24 | "CN/manual/manual.md": """---
25 | layout: default
26 | title: 手动标注
27 | nav_order: 3
28 | has_children: true
29 | """,
30 | "CN/manual/classification.md": """---
31 | layout: default
32 | title: 图像分类
33 | parent: 手动标注
34 | nav_order: 1
35 | """,
36 | "CN/manual/detection.md": """---
37 | layout: default
38 | title: 目标检测
39 | parent: 手动标注
40 | nav_order: 2
41 | """,
42 | "CN/manual/semantic_segmentation.md": """---
43 | layout: default
44 | title: 语义分割
45 | parent: 手动标注
46 | nav_order: 3
47 | """,
48 | "CN/manual/instance_segmentation.md": """---
49 | layout: default
50 | title: 实例分割
51 | parent: 手动标注
52 | nav_order: 4
53 | """,
54 | "CN/manual/ocr.md": """---
55 | layout: default
56 | title: OCR
57 | parent: 手动标注
58 | nav_order: 5
59 | """,
60 | # ML辅助标注
61 | "CN/ML/ml.md": """---
62 | layout: default
63 | title: 机器学习辅助标注
64 | nav_order: 4
65 | has_children: true
66 | """,
67 | "CN/ML/install_ml.md": """---
68 | layout: default
69 | title: 机器学习后端安装
70 | parent: 机器学习辅助标注
71 | nav_order: 1
72 | """,
73 | "CN/ML/auto_inference.md": """---
74 | layout: default
75 | title: 自动预标注使用方法
76 | parent: 机器学习辅助标注
77 | nav_order: 2
78 | """,
79 | "CN/ML/interactive_segmentation.md": """---
80 | layout: default
81 | title: 交互式分割
82 | parent: 机器学习辅助标注
83 | nav_order: 3
84 | """,
85 | "CN/training/training.md": """---
86 | layout: default
87 | title: 进行训练
88 | nav_order: 4
89 | has_children: true
90 | permalink: docs/training
91 | """,
92 | # 训练方式
93 | "CN/training/PdLabel_PdX.md": """---
94 | layout: default
95 | title: PaddleX 分类/检测/分割
96 | parent: 进行训练
97 | nav_order: 5
98 | """,
99 | "CN/training/PdLabel_PdClas.md": """---
100 | layout: default
101 | title: PaddleClas 花朵分类
102 | parent: 进行训练
103 | nav_order: 1
104 | """,
105 | "CN/training/PdLabel_PdDet.md": """---
106 | layout: default
107 | title: PaddleDetection 道路标志检测
108 | parent: 进行训练
109 | nav_order: 2
110 | """,
111 | "CN/training/PdLabel_PdSeg.md": """---
112 | layout: default
113 | title: PaddleSeg 图像分割
114 | parent: 进行训练
115 | nav_order: 3
116 | """,
117 | "CN/release_notes.md": """---
118 | layout: default
119 | title: 版本历史
120 | nav_order: 6
121 | """,
122 | "EN/README.md": """---
123 | layout: home
124 | title: Introduction
125 | nav_order: 0
126 | permalink: /
127 | """,
128 | }
129 |
130 | if len(sys.argv) == 1:
131 | base_url = "/PaddleLabel/"
132 | else:
133 | base_url = sys.argv[1]
134 |
135 | HERE = Path(__file__).parent.absolute()
136 | for name, header in headers.items():
137 | # if name != "CN/install.md":
138 | # continue
139 | path = HERE / name
140 | print("----")
141 | print(path)
142 | content = path.read_text()
143 | content = content.replace(".md", ".html")
144 | content = content.replace("/doc/", base_url)
145 | lines = content.split("\n")
146 | lines = [l for l in lines if not l.endswith(".mp4")]
147 | content = "\n".join(lines)
148 | # cmd = f"git rev-list --count HEAD {name}"
149 | cmd = f"git --no-pager log -1 --pretty='%ad' --date=iso {name}"
150 | # print(cmd)
151 | last_mod = subprocess.run(cmd.split(" "), capture_output=True, encoding="utf8").stdout.strip()
152 | if path.name != "README.md":
153 | header += f"permalink: {str(name).replace('.md', '.html').replace('CN/','').replace('EN/','')}\n"
154 | header += f"last_modified_date: {last_mod}\n---\n\n"
155 | print(header)
156 |
157 | content = header + content
158 | path.write_text(content)
159 |
--------------------------------------------------------------------------------
/docker-compose-dev.yml:
--------------------------------------------------------------------------------
1 | version: "3.8"
2 |
3 | volumes:
4 | pip:
5 |
6 | services:
7 | pp-labeling-backend:
8 | build:
9 | context: .
10 | dockerfile: Dockerfile.dev
11 | image: pp-label-backend:0.0.1
12 | container_name: "pp-label-backend"
13 | ports:
14 | - "5000:5000"
15 | volumes:
16 | - .:/app
17 | environment:
18 | - FLASK_ENV=development
19 | # command: /bin/sh -c "while sleep 1000; do :; done"
20 |
--------------------------------------------------------------------------------
/docstring_format.mustache:
--------------------------------------------------------------------------------
1 | {{! Numpy Docstring Template }}
2 | {{summaryPlaceholder}}
3 |
4 | {{extendedSummaryPlaceholder}}
5 | {{#parametersExist}}
6 |
7 | Parameters
8 | ----------
9 | {{#args}}
10 | {{var}} : {{typePlaceholder}}
11 | {{descriptionPlaceholder}}
12 | {{/args}}
13 | {{#kwargs}}
14 | {{var}} : {{typePlaceholder}}, optional
15 | {{descriptionPlaceholder}}. Defaults to {{&default}}
16 | {{/kwargs}}
17 | {{/parametersExist}}
18 | {{#returnsExist}}
19 |
20 | Returns
21 | -------
22 | {{#returns}}
23 | {{typePlaceholder}}
24 | {{descriptionPlaceholder}}
25 | {{/returns}}
26 | {{/returnsExist}}
27 | {{#yieldsExist}}
28 |
29 | Yields
30 | ------
31 | {{#yields}}
32 | {{typePlaceholder}}
33 | {{descriptionPlaceholder}}
34 | {{/yields}}
35 | {{/yieldsExist}}
36 | {{#exceptionsExist}}
37 |
38 | Raises
39 | ------
40 | {{#exceptions}}
41 | {{type}}
42 | {{descriptionPlaceholder}}
43 | {{/exceptions}}
44 | {{/exceptionsExist}}
45 |
--------------------------------------------------------------------------------
/paddlelabel/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import annotations
3 | import logging
4 |
5 | print("Starting PaddleLabel")
6 |
7 | # 1. get version
8 | from pathlib import Path
9 |
10 | __version__ = open((Path(__file__).parent / "version"), "r").read().strip()
11 |
12 |
13 | from dataclasses import dataclass
14 |
15 | # 2. global configs
16 | @dataclass
17 | class Configs:
18 | host: str = "127.0.0.1"
19 | port: int = 17995
20 | debug: bool = False # if running in debug mode
21 | log_level: int = logging.INFO
22 |
23 | # requests with the same request id arriving less than request_id_timeout s apart will be rejected
24 | request_id_timeout: float = 2
25 |
26 | """ file position settings """
27 | # _home: Path = Path(str(Path().home().absolute()).strip()) / ".paddlelabel"
28 | _home: Path = Path().home().absolute() / ".paddlelabel"
29 | install_base: Path = Path(__file__).absolute().parent # TODO: a better name?
30 |
31 | @property
32 | def home(self) -> Path:
33 | return self._home
34 |
35 | @home.setter
36 | def home(self, home_path: Path | str):
37 | home_path = Path(home_path)
38 | if not home_path.exists():
39 | home_path.mkdir(parents=True) # TODO: catch no permission
40 | self._home = home_path
41 |
42 | @property
43 | def sample_dir(self) -> Path:
44 | return self._home / "sample"
45 |
46 | # db settings
47 | db_engine: str = "sqlite"
48 | # db_head_version: str = "f47b7f5b73b9" # latest db version
49 | SQLALCHEMY_ECHO: bool = False
50 |
51 | @property
52 | def db_path(self) -> Path:
53 | return self._home / "paddlelabel.db"
54 |
55 | @property
56 | def db_url(self) -> str:
57 | return f"{self.db_engine}:///{str(self.db_path)}"
58 |
59 |
60 | configs = Configs()
61 |
62 | # 3. enable foreign key constraint for sqlite
63 | # TODO: run this conditionally based on db engine used
64 | from sqlalchemy.engine import Engine
65 | from sqlalchemy import event
66 |
67 |
68 | @event.listens_for(Engine, "connect")
69 | def set_sqlite_pragma(dbapi_connection, connection_record):
70 | cursor = dbapi_connection.cursor()
71 | cursor.execute("PRAGMA foreign_keys=ON")
72 | cursor.close()
73 |
--------------------------------------------------------------------------------
/paddlelabel/api/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import time
3 |
4 | from flask import abort, session, request
5 |
6 | from paddlelabel import configs
7 | from paddlelabel.config import app
8 |
9 | from . import controller
10 | from .model import Project, Label, Task, Data, Annotation, TaskCategory
11 | from .util import decode_token
12 | from . import rpc
13 |
14 | # TODO: is this specific to flask or is connexion function
15 | @app.before_request
16 | def check_request_id():
17 | request_id = request.headers.get("request_id", None)
18 | if request_id is None or len(request_id) == 0:
19 | return
20 | curr_time = time.time()
21 | if "request_ids" not in session:
22 | session["request_ids"] = [(curr_time, request_id)]
23 | return
24 | session["request_ids"] = list(
25 | filter(
26 | lambda item: curr_time - item[0] < configs.request_id_timeout,
27 | session["request_ids"],
28 | )
29 | )
30 | exist = False
31 | for ts, id in session["request_ids"]:
32 | if id == request_id:
33 | exist = True
34 | session["request_ids"].append((curr_time, request_id))
35 | if exist:
36 | abort(409, f"Duplicate request from {curr_time - ts}s ago")
37 |
--------------------------------------------------------------------------------
/paddlelabel/api/controller/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/api/controller/__init__.py
--------------------------------------------------------------------------------
/paddlelabel/api/controller/data.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import json
3 | import os
4 | import os.path as osp
5 | import random
6 |
7 | import cv2
8 | import flask
9 | import tempfile
10 |
11 | from .base import crud
12 | from ..model import Data, Project, Task
13 | from ..schema import DataSchema
14 | from paddlelabel.api.util import abort
15 | from paddlelabel.task.instance_segmentation import draw_mask
16 |
17 | get_all, get, post, put, delete = crud(Data, DataSchema)
18 |
19 |
20 | # TODO: dont use flask
21 | def get_image(data_id):
22 | # if random.random()<0.9:
23 | # abort("Mimic package loss", 404)
24 | _, data = Data._exists(data_id)
25 | path = data.path
26 | project_id = data.task.project_id
27 | data_dir = Project._get(project_id=project_id).data_dir
28 |
29 | folder = osp.join(data_dir, osp.dirname(path))
30 | file_name = osp.basename(path)
31 | # return flask.send_from_directory(data_dir, path)
32 |
33 | return flask.send_from_directory(folder, file_name)
34 |
35 | # data_path = osp.join(data_dir, path)
36 | # image = cv2.imread(data_path)
37 | # image_png = cv2.imencode(".png", image)
38 | # b64_string = base64.b64encode(image_png[1]).decode("utf-8")
39 | # return json.dumps({"image": b64_string}), 200
40 |
41 |
42 | def get_mask(data_id):
43 | _, data = Data._exists(data_id)
44 | mask = draw_mask(data, mask_type="pseudo")
45 | if mask is None:
46 | abort("This data probably doesn't have segmentation mask", 500)
47 |
48 | tempf = tempfile.NamedTemporaryFile(suffix=".png")
49 | cv2.imwrite(tempf.name, mask)
50 |
51 | return flask.send_from_directory(osp.dirname(tempf.name), osp.basename(tempf.name))
52 |
53 |
54 | def get_by_task(task_id):
55 | Task._exists(task_id)
56 | datas = Data._get(task_id=task_id, many=True)
57 | return DataSchema(many=True).dump(datas), 200
58 |
--------------------------------------------------------------------------------
/paddlelabel/api/controller/setting.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import json
3 |
4 | from ..model import TaskCategory
5 |
6 | from paddlelabel.config import se
7 |
8 |
9 | # TODO: change task_categories to project_category
10 | def init_site_settings(json_path):
11 | settings = json.loads(open(json_path, "r").read())
12 | task_categories = settings["site"]["task_categories"]
13 | for idx, (cat, handler) in task_categories.items():
14 | idx = int(idx)
15 | curr_cat = TaskCategory.query.filter(TaskCategory.task_category_id == idx).one_or_none()
16 | if curr_cat is None:
17 | curr_cat = TaskCategory(idx, cat, handler)
18 | se.add(curr_cat)
19 | se.commit()
20 |
--------------------------------------------------------------------------------
/paddlelabel/api/controller/tag.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import connexion
3 |
4 | from paddlelabel.config import db
5 | from .base import crud
6 | from ..model import Tag, Project, Task, TagTask
7 | from ..schema import TagSchema, TagTaskSchema
8 | from ..util import abort
9 |
10 |
11 | def pre_add(new_tag, se):
12 | curr_tag = Tag._get(project_id=new_tag.project_id, name=new_tag.name)
13 | if curr_tag is not None:
14 | abort(
15 | f"Duplicate tag with tag name {new_tag.name} under project {new_tag.project_id}",
16 | 409,
17 | )
18 | return new_tag
19 |
20 |
21 | get_all, get, post, put, delete = crud(Tag, TagSchema, [pre_add])
22 |
23 |
24 | def get_by_project(project_id):
25 | Project._exists(project_id)
26 | tags = Tag._get(project_id=project_id, many=True)
27 | return TagSchema(many=True).dump(tags), 200
28 |
29 |
30 | def get_by_task(task_id):
31 | Task._exists(task_id)
32 | tag_tasks = TagTask._get(task_id=task_id, many=True)
33 | tags = []
34 | for tag_task in tag_tasks:
35 | tag = Tag._get(tag_id=tag_task.tag_id)
36 | tags.append(tag)
37 | return TagSchema(many=True).dump(tags), 200
38 |
39 |
40 | def add_to_task(task_id):
41 | # 1. check
42 | # 1.1 check task exists
43 | task = Task._get(task_id=task_id)
44 | if task is None:
45 | abort(f"No task with task id {task_id}", 404)
46 |
47 | body = connexion.request.json
48 | tag_id = body["tag_id"]
49 | # 1.2 check tag exist
50 | tag = Tag._get(tag_id=tag_id)
51 | if tag is None:
52 | abort(f"No tag with tag id {tag_id}", 404)
53 | # 1.3 no duplicate records
54 | curr_tag_task = TagTask._get(task_id=task_id, tag_id=tag_id)
55 | if curr_tag_task is not None:
56 | abort(f"Task {task_id} is already tagged {tag_id}", 409)
57 | # 1.4 check tag under task
58 | project_id = Task._get(task_id=task_id).project_id
59 | if tag.project_id != project_id:
60 | abort(f"Tag {tag_id} is not under project {project_id}", 404)
61 |
62 | tag_task = TagTask(
63 | tag_id=tag_id,
64 | task_id=task_id,
65 | project_id=task.project_id,
66 | )
67 | db.session.add(tag_task)
68 | db.session.commit()
69 | tag_tasks = TagTask._get(task_id=task_id, many=True)
70 | tags = []
71 | for tag_task in tag_tasks:
72 | tags.append(tag_task.tag)
73 | return TagSchema(many=True).dump(tags), 201
74 |
--------------------------------------------------------------------------------
/paddlelabel/api/controller/task.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import connexion
3 |
4 | from paddlelabel.config import db
5 | from .base import crud
6 | from ..model import Task, Project
7 | from ..schema import TaskSchema
8 | from paddlelabel.api.util import abort, parse_order_by
9 |
10 | # TODO: reject tasks with same datas
11 | get_all, get, post, put, delete = crud(Task, TaskSchema)
12 |
13 |
14 | def get_by_project(project_id, order_by="created asc"):
15 | if connexion.request.method == "HEAD":
16 | return get_stat_by_project(project_id)
17 | Project._exists(project_id)
18 | order = parse_order_by(Task, order_by)
19 |
20 | tasks = Task.query.filter(Task.project_id == project_id).order_by(order).all()
21 | return TaskSchema(many=True).dump(tasks), 200
22 |
23 |
24 | # TODO: dont lazy load annotations in tasks
25 | def get_stat_by_project(project_id):
26 | Project._exists(project_id)
27 | tasks = Task.query.filter(Task.project_id == project_id).all()
28 | ann_count = 0
29 | for task in tasks:
30 | if len(task.annotations) != 0:
31 | ann_count += 1
32 | res = {"finished": ann_count, "total": len(tasks)}
33 | return res, 200, res
34 |
35 |
36 | def set_all_by_project(project_id):
37 | if "data_predicted" in connexion.request.json.keys():
38 | for task in Task._get(project_id=project_id, many=True):
39 | for data in task.datas:
40 | data.predicted = connexion.request.json["data_predicted"]
41 | db.session.commit()
42 |
--------------------------------------------------------------------------------
/paddlelabel/api/controller/user.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import re
3 |
4 | from marshmallow import fields
5 | import uuid
6 | from werkzeug.security import generate_password_hash, check_password_hash
7 |
8 | from ..model import User
9 | from ..schema import UserSchema
10 | from .base import crud
11 | from ..util import abort, generate_token
12 |
13 |
14 | def validata_email(email):
15 | regex = re.compile(r"([A-Za-z0-9]+[.-_])*[A-Za-z0-9]+@[A-Za-z0-9-]+(\.[A-Z|a-z]{2,})+")
16 | if re.fullmatch(regex, email):
17 | return True
18 | return False
19 |
20 |
21 | def pre_add(user, se):
22 | if not validata_email(user.email):
23 | abort("Email is not valid", 400)
24 | user.password = generate_password_hash(user.password, method="sha256")
25 | user.uuid = str(uuid.uuid4())
26 | return user
27 |
28 |
29 | def pre_put(curr_user, new_user, se):
30 | if "email" in new_user.keys():
31 | if not validata_email(new_user["email"]):
32 | abort("Email is not valid", 400)
33 | if "password" in new_user.keys():
34 | new_user["password"] = generate_password_hash(new_user["password"], method="sha256")
35 |
36 |
37 | get_all, get, post, put, delete = crud(User, UserSchema, [pre_add, pre_put])
38 |
39 |
40 | def login():
41 | r = connexion.request.json
42 | username = r.get("username", None)
43 | password = r.get("password", None)
44 | if username is None:
45 | abort("Need username to login", 401)
46 | if password is None:
47 | abort("Need password to login", 401)
48 | user = User._get(username=username)
49 | if user is None:
50 | abort(f"Username or password is wrong", 401)
51 | if check_password_hash(user.password, password):
52 | return generate_token(user.uuid)
53 | else:
54 | abort(f"Username or password is wrong", 401)
55 |
--------------------------------------------------------------------------------
/paddlelabel/api/model/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from .project import Project
3 | from .label import Label
4 | from .task import Task
5 | from .data import Data
6 | from .annotation import Annotation
7 | from .user import User
8 | from .setting import TaskCategory, AlembicVersion
9 | from .tag import Tag
10 | from .tag_task import TagTask
11 |
--------------------------------------------------------------------------------
/paddlelabel/api/model/annotation.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from paddlelabel.config import db
3 | from paddlelabel.api.util import nncol
4 | from .base import BaseModel
5 |
6 |
7 | class Annotation(BaseModel):
8 | __tablename__ = "annotation"
9 | __table_args__ = {"comment": "Stores all annotations"}
10 | annotation_id = nncol(db.Integer(), primary_key=True)
11 | frontend_id = db.Column(db.Integer()) # unique id within data, start from 1
12 | result = db.Column(db.String())
13 | type = db.Column(db.String())
14 | label_id = nncol(db.Integer(), db.ForeignKey("label.label_id", ondelete="CASCADE"))
15 | data_id = db.Column(db.Integer(), db.ForeignKey("data.data_id", ondelete="CASCADE"))
16 | predicted_by = db.Column(db.String())
17 |
18 | # TODO: remove
19 | task_id = nncol(db.Integer(), db.ForeignKey("task.task_id", ondelete="CASCADE"))
20 | # task = db.relationship("Task")
21 | project_id = nncol(db.Integer(), db.ForeignKey("project.project_id"))
22 |
23 | _immutables = BaseModel._immutables + ["annotation_id", "label_id", "task_id", "slice_id"]
24 |
--------------------------------------------------------------------------------
/paddlelabel/api/model/base.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import annotations
3 |
4 | from datetime import datetime
5 | from typing import List, TypeVar, Type, Tuple, overload
6 |
7 | from paddlelabel.config import db
8 | from paddlelabel.api.util import nncol, abort
9 | from paddlelabel.util import pyVerGt
10 |
11 | T = TypeVar("T")
12 | # TODO: nn string col cant be ""
13 | class BaseModel(db.Model):
14 | __abstract__ = True
15 | __tablename__ = ""
16 | __table_args__ = {"comment": ""}
17 | created = nncol(db.DateTime, default=datetime.utcnow)
18 | modified = nncol(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
19 |
20 | _immutables = ["created", "modified", "immutables"]
21 | _nested = ["project"]
22 |
23 | @classmethod
24 | @property
25 | def _cols(cls):
26 | return [c.key for c in cls.__table__.columns]
27 |
28 | def __repr__(self):
29 | s = f"Object {self.__tablename__}: "
30 | for att in dir(self):
31 | if (
32 | att[0] != "_"
33 | and att[-1] != "s"
34 | and att not in ["query", "registry", "metadata", "query_class"]
35 | and att not in self._nested
36 | ):
37 | s += f"{att}: {getattr(self, att)} "
38 | s += "\n"
39 | return s
40 |
41 | @classmethod
42 | def _exists(cls: Type[T], item_id, throw=True) -> Tuple[bool, None | T]:
43 | item = cls.query.filter(getattr(cls, cls.__tablename__ + "_id") == item_id).one_or_none()
44 | if item is None:
45 | if throw:
46 | abort(f"No {cls.__tablename__} with id : {item_id}", 404)
47 | else:
48 | return False, None
49 | return True, item
50 |
51 | @overload
52 | @classmethod
53 | def _get(cls: Type[T], many: bool, **kwargs) -> List[T]:
54 | ...
55 |
56 | @overload
57 | @classmethod
58 | def _get(cls: Type[T], **kwargs) -> T | None:
59 | ...
60 |
61 | @classmethod
62 | def _get(cls, many: bool = False, **kwargs):
63 | if pyVerGt(): # skip check for py < 3.9
64 | for key in kwargs.keys():
65 | if key not in cls._cols:
66 | raise AttributeError(f"Model {cls.__tablename__} don't have attribute {key}")
67 |
68 | conditions = {}
69 | for k, v in list(kwargs.items()):
70 | conditions[k] = v
71 | if many:
72 | items = cls.query.filter_by(**conditions).all()
73 | return items
74 |
75 | item = cls.query.filter_by(**conditions).one_or_none()
76 | return item
77 |
--------------------------------------------------------------------------------
/paddlelabel/api/model/data.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from paddlelabel.config import db
3 | from ..util import nncol
4 | from .base import BaseModel
5 |
6 |
7 | class Data(BaseModel):
8 | __tablename__ = "data"
9 | __table_args__ = {"comment": "Contains all the data files"}
10 | data_id = nncol(db.Integer(), primary_key=True)
11 | task_id = db.Column(db.Integer(), db.ForeignKey("task.task_id", ondelete="CASCADE"))
12 | # task = db.relationship("Task", lazy="selectin")
13 | annotations = db.relationship("Annotation", lazy="selectin", cascade="all, delete-orphan")
14 | path = nncol(db.String())
15 | size = db.Column(db.String()) # , separated string. natural image: 1,height,width
16 | predicted = db.Column(db.Boolean())
17 |
18 | _immutables = BaseModel._immutables + ["data_id", "task_id"]
19 |
--------------------------------------------------------------------------------
/paddlelabel/api/model/label.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from datetime import datetime
3 |
4 | from paddlelabel.config import db
5 | from ..util import nncol
6 | from .base import BaseModel
7 |
8 |
9 | class Label(BaseModel):
10 | __tablename__ = "label"
11 | __table_args__ = {"comment": "Contains all the label information"}
12 | label_id = nncol(db.Integer(), primary_key=True)
13 | id = nncol(db.Integer())
14 | project_id = db.Column(db.Integer(), db.ForeignKey("project.project_id")) # TODO: why missing project_id when nncol
15 | name = nncol(db.String())
16 | color = db.Column(db.String())
17 | comment = db.Column(db.String())
18 | annotations = db.relationship("Annotation", lazy="noload", backref="label") # cascade="all, delete-orphan"
19 | super_category_id = db.Column(db.Integer()) # TODO: foreign key
20 | _immutables = BaseModel._immutables + ["label_id", "project_id"]
21 |
--------------------------------------------------------------------------------
/paddlelabel/api/model/project.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import json
3 |
4 | from paddlelabel.config import db
5 | from paddlelabel.api.util import nncol
6 |
7 | # TODO: circular risk
8 | from .base import BaseModel
9 |
10 |
11 | class Project(BaseModel):
12 | __tablename__ = "project"
13 | __table_args__ = {"comment": "Stores information and settings for each project"}
14 | project_id = nncol(db.Integer, primary_key=True)
15 | name = nncol(db.String(), unique=True)
16 | description = db.Column(db.String())
17 | task_category_id = db.Column(db.Integer(), db.ForeignKey("taskCategory.task_category_id"))
18 | task_category = db.relationship("TaskCategory")
19 | data_dir = nncol(db.String(), unique=True)
20 | label_dir = db.Column(db.String(), unique=True) # TODO: remove
21 | labels = db.relationship(
22 | "Label",
23 | lazy="selectin",
24 | cascade="all, delete-orphan",
25 | )
26 | tasks = db.relationship("Task", lazy="noload", cascade="all, delete-orphan")
27 | annotations = db.relationship("Annotation", lazy="noload", cascade="all, delete-orphan")
28 | label_format = db.Column(db.String())
29 | other_settings = db.Column(db.String())
30 |
31 | _immutables = BaseModel._immutables + ["project_id", "task_category_id"]
32 |
33 | def _get_other_settings(self):
34 | if self.other_settings is None:
35 | return {}
36 | return json.loads(self.other_settings)
37 |
--------------------------------------------------------------------------------
/paddlelabel/api/model/setting.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import os.path as osp
3 |
4 | from functools import total_ordering
5 |
6 | from paddlelabel.config import db
7 | from paddlelabel.api.util import nncol
8 | from .base import BaseModel
9 |
10 |
11 | class TaskCategory(BaseModel):
12 | __tablename__ = "taskCategory"
13 | task_category_id = nncol(
14 | db.Integer(),
15 | primary_key=True,
16 | autoincrement=False,
17 | )
18 | name = nncol(db.String(), unique=True)
19 | handler = db.Column(db.String())
20 |
21 | def __init__(self, task_category_id, name, handler):
22 | super().__init__()
23 | self.task_category_id = task_category_id
24 | self.name = name
25 | if len(handler) == 0:
26 | self.handler = None
27 | else:
28 | self.handler = handler
29 |
30 |
31 | class AlembicVersion(db.Model):
32 | __tablename__ = "alembic_version"
33 | version_num = db.Column(db.String(), primary_key=True)
34 |
--------------------------------------------------------------------------------
/paddlelabel/api/model/tag.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from paddlelabel.config import db
3 | from paddlelabel.api.util import nncol
4 | from .base import BaseModel
5 |
6 |
7 | class Tag(BaseModel):
8 | __tablename__ = "tag"
9 | __table_args__ = {"comment": "Contains all the tags"}
10 | tag_id = nncol(db.Integer(), primary_key=True)
11 | project_id = nncol(db.Integer(), db.ForeignKey("project.project_id"))
12 | name = nncol(db.String())
13 | color = db.Column(db.String())
14 | comment = db.Column(db.String())
15 |
16 | _immutables = BaseModel._immutables + ["tag_id", "project_id"]
17 |
--------------------------------------------------------------------------------
/paddlelabel/api/model/tag_task.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from paddlelabel.config import db
3 | from paddlelabel.api.util import nncol
4 | from .base import BaseModel
5 |
6 |
7 | class TagTask(BaseModel):
8 | __tablename__ = "tagTask"
9 | __table_args__ = {"comment": "Tag and task intersect"}
10 | tag_task_id = nncol(db.Integer(), primary_key=True)
11 | project_id = nncol(db.Integer(), db.ForeignKey("project.project_id"))
12 | tag_id = nncol(db.Integer(), db.ForeignKey("tag.tag_id"))
13 | task_id = nncol(db.Integer(), db.ForeignKey("task.task_id"))
14 | tag = db.relationship("Tag")
15 |
16 | _immutables = BaseModel._immutables + [
17 | "tag_task_id",
18 | "project_id",
19 | "tag_id",
20 | "task_id",
21 | ]
22 |
--------------------------------------------------------------------------------
/paddlelabel/api/model/task.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from datetime import datetime
3 |
4 | from sqlalchemy.orm import backref
5 |
6 | from paddlelabel.config import db
7 | from ..util import nncol
8 | from .annotation import Annotation
9 | from .project import Project
10 | from .base import BaseModel
11 |
12 |
13 | class Task(BaseModel):
14 | __tablename__ = "task"
15 | __table_args__ = {"comment": "Contains all the tasks"}
16 | task_id = nncol(db.Integer(), primary_key=True)
17 | project_id = nncol(
18 | db.Integer(),
19 | db.ForeignKey("project.project_id", ondelete="CASCADE"),
20 | )
21 | datas = db.relationship("Data", lazy="selectin", backref="task", cascade="all, delete-orphan")
22 | annotations = db.relationship("Annotation", lazy="selectin", backref="task", cascade="all, delete-orphan")
23 | # TODO: split with tag
24 | set = nncol(db.Integer()) # 0 train, 1 val, 2 test
25 |
--------------------------------------------------------------------------------
/paddlelabel/api/model/user.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from datetime import datetime
3 |
4 | from paddlelabel.config import db
5 | from paddlelabel.api.util import nncol
6 |
7 | from .base import BaseModel
8 |
9 |
10 | class User(BaseModel):
11 | __tablename__ = "user"
12 | __table_args__ = {"comment": "Stores all user info"}
13 | user_id = nncol(db.Integer, primary_key=True)
14 | uuid = nncol(db.String(), unique=True)
15 | username = nncol(db.String(), unique=True)
16 | email = nncol(db.String())
17 | password = nncol(db.String())
18 | role_id = nncol(db.Integer())
19 |
20 | _immutables = BaseModel._immutables + ["user_id", "uuid"]
21 |
--------------------------------------------------------------------------------
/paddlelabel/api/rpc/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/api/rpc/__init__.py
--------------------------------------------------------------------------------
/paddlelabel/api/rpc/cache.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import connexion
3 | import time
4 |
5 | cache_dict = {}
6 |
7 |
8 | def create_cache():
9 | content = connexion.request.json["content"]
10 | global cache_dict
11 | cache_id = str(time.time())
12 | cache_dict[cache_id] = content
13 | # print(cache_id, content)
14 | return {"cache_id": cache_id}
15 |
16 |
17 | def get_cache(cache_id):
18 | # print(cache_id, type(cache_id), cache_dict)
19 | content = cache_dict.get(cache_id, None)
20 | if content is None:
21 | return {"title": f"no cache record with cache_id {cache_id} found"}, 404
22 | return {"content": content}
23 |
--------------------------------------------------------------------------------
/paddlelabel/api/rpc/debug.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import logging
3 |
4 | logger = logging.getLogger("paddlelabel")
5 |
6 |
7 | def cmdOutputDebugId(debug_id):
8 | logger.debug(f"Debug ID: {debug_id}")
9 | return "OK", 200
10 |
--------------------------------------------------------------------------------
/paddlelabel/api/rpc/file.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | def get_folders():
3 | raise NotImplementedError()
4 |
5 | # path = connexion.request.json.get("path", None)
6 | # if path is None:
7 | # path = ""
8 | # target = osp.join(data_base_dir, path)
9 | # target = osp.abspath(target)
10 | # # print(target, type(target))
11 |
12 | # if not target[-1] == os.sep:
13 | # target += os.sep
14 | # if not target.startswith(osp.abspath(data_base_dir) + os.sep):
15 | # abort("Can only request folders under data_base_dir", 500)
16 | # if not osp.exists(target):
17 | # return [], 200
18 | # return next(os.walk(target))[1], 200
19 |
--------------------------------------------------------------------------------
/paddlelabel/api/rpc/monitor.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import paddlelabel
3 |
4 |
5 | def get_version():
6 | return paddlelabel.__version__, 200
7 |
--------------------------------------------------------------------------------
/paddlelabel/api/rpc/util/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/api/rpc/util/__init__.py
--------------------------------------------------------------------------------
/paddlelabel/api/schema/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from .project import ProjectSchema
3 | from .label import LabelSchema
4 | from .task import TaskSchema
5 | from .data import DataSchema
6 | from .annotation import AnnotationSchema
7 | from .user import UserSchema
8 | from .setting import TaskCategorySchema
9 | from .tag import TagSchema
10 | from .tag_task import TagTaskSchema
11 |
--------------------------------------------------------------------------------
/paddlelabel/api/schema/annotation.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from marshmallow import fields
3 |
4 |
5 | from paddlelabel.api.model import Annotation
6 | from .base import BaseSchema
7 |
8 |
9 | class AnnotationSchema(BaseSchema):
10 | class Meta(BaseSchema.Meta):
11 | model = Annotation
12 |
13 | # not required when calling api
14 | project_id = fields.Integer()
15 | task_id = fields.Integer()
16 | # task = fields.Nested("TaskSchema", exclude=("annotations", "datas"))
17 | label = fields.Nested("LabelSchema")
18 |
--------------------------------------------------------------------------------
/paddlelabel/api/schema/base.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from paddlelabel.config import ma, db
3 |
4 |
5 | class BaseSchema(ma.SQLAlchemyAutoSchema):
6 | class Meta:
7 | include_fk = True
8 | load_instance = True
9 | sqla_session = db.session
10 |
--------------------------------------------------------------------------------
/paddlelabel/api/schema/data.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from marshmallow import fields, post_dump
3 |
4 | from paddlelabel.api.model import Data
5 | from .base import BaseSchema
6 | from paddlelabel.api.schema.util import str2sault
7 |
8 |
9 | class DataSchema(BaseSchema):
10 | class Meta(BaseSchema.Meta):
11 | model = Data
12 |
13 | @post_dump
14 | def post_dump_action(self, data, **kwargs):
15 | data["sault"] = str2sault(data["path"] + data["created"])
16 | return data
17 |
18 | # task = fields.Nested("TaskSchema", exclude=("datas", "annotations"))
19 |
--------------------------------------------------------------------------------
/paddlelabel/api/schema/label.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from marshmallow import fields
3 |
4 | from paddlelabel.api.model import Label
5 | from .base import BaseSchema
6 |
7 |
8 | class LabelSchema(BaseSchema):
9 | class Meta(BaseSchema.Meta):
10 | model = Label
11 |
12 | id = fields.Integer()
13 |
--------------------------------------------------------------------------------
/paddlelabel/api/schema/project.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import json
3 |
4 | from marshmallow import pre_load, post_dump, fields
5 |
6 | from paddlelabel.api.model import Project
7 | from paddlelabel.api.schema.util import str2sault
8 | from paddlelabel.api.schema.base import BaseSchema
9 |
10 |
11 | class ProjectSchema(BaseSchema):
12 | class Meta(BaseSchema.Meta):
13 | model = Project
14 | # include_relationships = True
15 |
16 | label_dir = fields.String(allow_none=True)
17 | task_category = fields.Nested("TaskCategorySchema")
18 | labels = fields.List(fields.Nested("LabelSchema"))
19 |
20 | @pre_load
21 | def pre_load_action(self, data, **kwargs):
22 | if "label_dir" in data.keys() and data["label_dir"] == "":
23 | data["label_dir"] = None
24 |
25 | if "other_settings" in data.keys():
26 | data["other_settings"] = json.dumps(data["other_settings"])
27 | return data
28 |
29 | @post_dump
30 | def pre_dump_action(self, project, **kwargs):
31 | if "other_settings" in project.keys() and project["other_settings"] is not None:
32 | project["other_settings"] = json.loads(project["other_settings"])
33 | project["upid"] = str2sault(project["data_dir"] + project["created"])
34 | return project
35 |
--------------------------------------------------------------------------------
/paddlelabel/api/schema/setting.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from paddlelabel.api.model import TaskCategory
3 | from .base import BaseSchema
4 |
5 |
6 | class TaskCategorySchema(BaseSchema):
7 | class Meta(BaseSchema.Meta):
8 | model = TaskCategory
9 |
--------------------------------------------------------------------------------
/paddlelabel/api/schema/tag.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from marshmallow import fields
3 |
4 |
5 | from paddlelabel.api.model import Tag
6 | from .base import BaseSchema
7 |
8 |
9 | class TagSchema(BaseSchema):
10 | class Meta(BaseSchema.Meta):
11 | model = Tag
12 |
--------------------------------------------------------------------------------
/paddlelabel/api/schema/tag_task.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from marshmallow import fields
3 |
4 |
5 | from paddlelabel.api.model import TagTask
6 | from .base import BaseSchema
7 |
8 |
9 | class TagTaskSchema(BaseSchema):
10 | class Meta(BaseSchema.Meta):
11 | model = TagTask
12 |
--------------------------------------------------------------------------------
/paddlelabel/api/schema/task.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import json
3 | import time
4 |
5 | from marshmallow import post_load, pre_load, pre_dump, post_dump, fields
6 | from marshmallow.fields import Nested
7 |
8 | from paddlelabel.api.model import Task
9 | from paddlelabel.api.schema.util import str2sault
10 | from .base import BaseSchema
11 |
12 |
13 | class TaskSchema(BaseSchema):
14 | class Meta(BaseSchema.Meta):
15 | model = Task
16 |
17 | # project = Nested("ProjectSchema")
18 | annotations = fields.List(Nested("AnnotationSchema"), exclude=("task",))
19 | data_paths = fields.List(fields.String())
20 | # datas = fields.List(Nested("DataSchema"), exclude=("task",))
21 |
22 | # # TODO: confirm data['result'] dont cause trouble
23 | @pre_dump
24 | def output(self, task, **kwargs):
25 | paths = []
26 | for data in task.datas:
27 | paths.append(f"/datas/{data.data_id}/image?sault={str2sault(data.path+str(data.created))}")
28 | task.data_paths = paths
29 | return task
30 |
--------------------------------------------------------------------------------
/paddlelabel/api/schema/user.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from marshmallow import pre_load, fields
3 |
4 | from paddlelabel.api.model import User
5 | from .base import BaseSchema
6 |
7 |
8 | class UserSchema(BaseSchema):
9 | class Meta(BaseSchema.Meta):
10 | model = User
11 |
12 | uuid = fields.String()
13 |
--------------------------------------------------------------------------------
/paddlelabel/api/schema/util.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import hashlib
3 |
4 |
5 | def str2sault(seed):
6 | return hashlib.md5(seed.encode("utf-8")).hexdigest()[:20]
7 |
--------------------------------------------------------------------------------
/paddlelabel/api/util.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import functools
3 | import time
4 |
5 | # import logging
6 |
7 | import connexion
8 | import sqlalchemy as sa
9 |
10 | from paddlelabel.util import camel2snake
11 |
12 |
13 | # sa defaults to nullable=True
14 | nncol = functools.partial(sa.Column, nullable=False)
15 |
16 | # TODO: settle on how to use detail and title
17 | def abort(detail: str, status: int, title: str = ""):
18 | # logging.getLogger("paddlelabel").exception(detail)
19 | detail = detail.replace("\n", " ")
20 | title = title.replace("\n", " ")
21 | raise connexion.exceptions.ProblemException(
22 | detail=detail,
23 | title=title if len(title) != 0 else detail,
24 | status=status,
25 | headers={"charset": "utf-8"},
26 | )
27 |
28 |
29 | # TODO: move to config
30 | JWT_ISSUER = "paddlelabel"
31 | JWT_SECRET = "change_this"
32 | JWT_LIFETIME_SECONDS = 43200 # 12h
33 | JWT_ALGORITHM = "HS256"
34 |
35 |
36 | def generate_token(uuid):
37 | timestamp = int(time.time())
38 | payload = {
39 | "iss": JWT_ISSUER,
40 | "iat": timestamp,
41 | "exp": timestamp + JWT_LIFETIME_SECONDS,
42 | "sub": uuid,
43 | }
44 | return jwt.encode(payload, JWT_SECRET, algorithm=JWT_ALGORITHM)
45 |
46 |
47 | def decode_token(token):
48 | try:
49 | return jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM])
50 | except JWTError as e:
51 | raise Unauthorized from e
52 |
53 |
54 | def parse_order_by(modal, order_by):
55 | order_by = order_by.split(" ")
56 | if len(order_by) == 2:
57 | key, sort_dir = order_by
58 | # print(key, sort_dir)
59 | if "asc" in sort_dir:
60 | sort_dir = "asc"
61 | else:
62 | sort_dir = "desc"
63 | else:
64 | key = order_by[0]
65 | sort_dir = "acs"
66 | key = camel2snake(key)
67 |
68 | try:
69 | order = getattr(getattr(modal, key), sort_dir)()
70 | except:
71 | order = modal.created.asc()
72 | return order
73 |
--------------------------------------------------------------------------------
/paddlelabel/config.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # TODO: move all functions in this file to serve.py
3 | from pathlib import Path
4 | import logging
5 |
6 | import connexion
7 | from flask_sqlalchemy import SQLAlchemy # TODO: remove
8 | from flask_marshmallow import Marshmallow # TODO: remove
9 |
10 | from paddlelabel.util import rand_string
11 | from paddlelabel import configs
12 |
13 | HERE = Path(__file__).parent.absolute()
14 | logger = logging.getLogger("paddlelabel")
15 |
16 | # if not configs.db_path.parent.exists():
17 | # configs.db_path.parent.mkdir()
18 |
19 | logger.info(f"Database path: {configs.db_url}")
20 |
21 | connexion_app = connexion.App("PaddleLabel")
22 | app = connexion_app.app
23 | app.config["SQLALCHEMY_DATABASE_URI"] = configs.db_url
24 | app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
25 | app.config["SQLALCHEMY_ECHO"] = configs.SQLALCHEMY_ECHO
26 | app.config["SECRET_KEY"] = rand_string(30)
27 |
28 | app.static_url_path = "/static"
29 | app.static_folder = str((HERE / "static").absolute())
30 |
31 | db = SQLAlchemy(app)
32 | se = db.session
33 | ma = Marshmallow(app)
34 |
--------------------------------------------------------------------------------
/paddlelabel/dbmigration/README.md:
--------------------------------------------------------------------------------
1 | Generate new revision
2 |
3 | ```shell
4 | cd paddlelabel
5 | alembic revision --autogenerate -m ""
6 | ```
7 |
--------------------------------------------------------------------------------
/paddlelabel/dbmigration/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/dbmigration/__init__.py
--------------------------------------------------------------------------------
/paddlelabel/dbmigration/env.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from logging.config import fileConfig
3 |
4 | from sqlalchemy import engine_from_config
5 | from sqlalchemy import pool
6 |
7 | from alembic import context
8 |
9 | # this is the Alembic Config object, which provides
10 | # access to the values within the .ini file in use.
11 | config = context.config
12 | # Interpret the config file for Python logging.
13 | # This line sets up loggers basically.
14 | if config.config_file_name is not None:
15 | fileConfig(config.config_file_name)
16 |
17 | # add your model's MetaData object here
18 | # for 'autogenerate' support
19 | from paddlelabel import config as pdlabel_config
20 |
21 | target_metadata = pdlabel_config.db.metadata
22 | # target_metadata = None
23 |
24 | # other values from the config, defined by the needs of env.py,
25 | # can be acquired:
26 | # my_important_option = config.get_main_option("my_important_option")
27 | # ... etc.
28 |
29 |
30 | def run_migrations_offline() -> None:
31 | """Run migrations in 'offline' mode.
32 |
33 | This configures the context with just a URL
34 | and not an Engine, though an Engine is acceptable
35 | here as well. By skipping the Engine creation
36 | we don't even need a DBAPI to be available.
37 |
38 | Calls to context.execute() here emit the given string to the
39 | script output.
40 |
41 | """
42 | url = config.get_main_option("sqlalchemy.url")
43 | context.configure(
44 | url=url,
45 | target_metadata=target_metadata,
46 | literal_binds=True,
47 | dialect_opts={"paramstyle": "named"},
48 | )
49 |
50 | with context.begin_transaction():
51 | context.run_migrations()
52 |
53 |
54 | def run_migrations_online() -> None:
55 | """Run migrations in 'online' mode.
56 |
57 | In this scenario we need to create an Engine
58 | and associate a connection with the context.
59 |
60 | """
61 | connectable = engine_from_config(
62 | config.get_section(config.config_ini_section),
63 | prefix="sqlalchemy.",
64 | poolclass=pool.NullPool,
65 | )
66 |
67 | with connectable.connect() as connection:
68 | context.configure(connection=connection, target_metadata=target_metadata)
69 |
70 | with context.begin_transaction():
71 | context.run_migrations()
72 |
73 |
74 | if context.is_offline_mode():
75 | run_migrations_offline()
76 | else:
77 | run_migrations_online()
78 |
--------------------------------------------------------------------------------
/paddlelabel/dbmigration/script.py.mako:
--------------------------------------------------------------------------------
1 | """${message}
2 |
3 | Revision ID: ${up_revision}
4 | Revises: ${down_revision | comma,n}
5 | Create Date: ${create_date}
6 |
7 | """
8 | from alembic import op
9 | import sqlalchemy as sa
10 | ${imports if imports else ""}
11 |
12 | # revision identifiers, used by Alembic.
13 | revision = ${repr(up_revision)}
14 | down_revision = ${repr(down_revision)}
15 | branch_labels = ${repr(branch_labels)}
16 | depends_on = ${repr(depends_on)}
17 |
18 |
19 | def upgrade() -> None:
20 | ${upgrades if upgrades else "pass"}
21 |
22 |
23 | def downgrade() -> None:
24 | ${downgrades if downgrades else "pass"}
25 |
--------------------------------------------------------------------------------
/paddlelabel/dbmigration/versions/61968cbf48e8_v0_1_3.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """v0.1.3. Add annotation.predicted_by
3 |
4 | Revision ID: 61968cbf48e8
5 | Revises: 23c1bf9b7f48
6 | Create Date: 2022-10-19 02:03:41.383698
7 |
8 | """
9 | from alembic import op
10 | import sqlalchemy as sa
11 |
12 |
13 | # revision identifiers, used by Alembic.
14 | revision = "61968cbf48e8"
15 | down_revision = "23c1bf9b7f48"
16 | branch_labels = None
17 | depends_on = None
18 |
19 |
20 | def upgrade() -> None:
21 | # ### commands auto generated by Alembic - please adjust! ###
22 | op.add_column("annotation", sa.Column("predicted_by", sa.String(), nullable=True))
23 | # ### end Alembic commands ###
24 |
25 |
26 | def downgrade() -> None:
27 | # ### commands auto generated by Alembic - please adjust! ###
28 | op.drop_column("annotation", "predicted_by")
29 | # ### end Alembic commands ###
30 |
--------------------------------------------------------------------------------
/paddlelabel/dbmigration/versions/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/dbmigration/versions/__init__.py
--------------------------------------------------------------------------------
/paddlelabel/dbmigration/versions/a609821ce310_v0_1_4.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """v0.1.4. Add data.predicted
3 |
4 | Revision ID: a609821ce310
5 | Revises: 61968cbf48e8
6 | Create Date: 2022-10-22 03:58:11.232173
7 |
8 | """
9 | from alembic import op
10 | import sqlalchemy as sa
11 |
12 |
13 | # revision identifiers, used by Alembic.
14 | revision = "a609821ce310"
15 | down_revision = "61968cbf48e8"
16 | branch_labels = None
17 | depends_on = None
18 |
19 |
20 | def upgrade() -> None:
21 | # ### commands auto generated by Alembic - please adjust! ###
22 | op.add_column("data", sa.Column("predicted", sa.Boolean(), nullable=True))
23 | # ### end Alembic commands ###
24 |
25 |
26 | def downgrade() -> None:
27 | # ### commands auto generated by Alembic - please adjust! ###
28 | op.drop_column("data", "predicted")
29 | # ### end Alembic commands ###
30 |
--------------------------------------------------------------------------------
/paddlelabel/dbmigration/versions/e660f34b820d_v1_0_1.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """v1.0.1
3 | - reset sample folder
4 |
5 | Revision ID: e660f34b820d
6 | Revises: f47b7f5b73b9
7 | Create Date: 2023-01-24 06:35:13.150458
8 |
9 | """
10 | from alembic import op
11 | import sqlalchemy as sa
12 |
13 |
14 | # revision identifiers, used by Alembic.
15 | revision = "e660f34b820d"
16 | down_revision = "f47b7f5b73b9"
17 | branch_labels = None
18 | depends_on = None
19 |
20 |
21 | def upgrade() -> None:
22 | # ### commands auto generated by Alembic - please adjust! ###
23 | from paddlelabel.api.controller.sample import reset_samples
24 |
25 | reset_samples()
26 | # ### end Alembic commands ###
27 |
28 |
29 | def downgrade() -> None:
30 | # ### commands auto generated by Alembic - please adjust! ###
31 | pass
32 | # ### end Alembic commands ###
33 |
--------------------------------------------------------------------------------
/paddlelabel/dbmigration/versions/f47b7f5b73b9_v1_0_0.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """v1.0.0
3 | - Make sure the size of all tasks are 1,h,w
4 |
5 | Revision ID: f47b7f5b73b9
6 | Revises: a609821ce310
7 | Create Date: 2023-01-09 18:31:50.399688
8 |
9 | """
10 | from pathlib import Path
11 |
12 | from paddlelabel.api.model import Project, Task
13 | from paddlelabel.config import se
14 | from paddlelabel.io.image import getSize
15 |
16 | # revision identifiers, used by Alembic.
17 | revision = "f47b7f5b73b9"
18 | down_revision = "a609821ce310"
19 | branch_labels = None
20 | depends_on = None
21 |
22 |
23 | def upgrade() -> None:
24 | # ### commands auto generated by Alembic - please adjust! ###
25 | projects = Project.query.all()
26 | pjid2data_dir = {p.project_id: Path(p.data_dir) for p in projects}
27 |
28 | tasks = Task.query.all()
29 | for task in tasks:
30 | data = task.datas[0]
31 | img_path = Path(pjid2data_dir[task.project_id]) / data.path
32 | s, _, _ = getSize(img_path)
33 | data.size = s
34 | se.commit()
35 |
36 | # ### end Alembic commands ###
37 |
38 |
39 | def downgrade() -> None:
40 | # ### commands auto generated by Alembic - please adjust! ###
41 | pass
42 | # ### end Alembic commands ###
43 |
--------------------------------------------------------------------------------
/paddlelabel/default_setting.json:
--------------------------------------------------------------------------------
1 | {
2 | "site": {
3 | "task_categories": {
4 | "1": [
5 | "classification",
6 | "paddlelabel.task.Classification"
7 | ],
8 | "2": [
9 | "detection",
10 | "paddlelabel.task.Detection"
11 | ],
12 | "3": [
13 | "semantic_segmentation",
14 | "paddlelabel.task.SemanticSegmentation"
15 | ],
16 | "4": [
17 | "instance_segmentation",
18 | "paddlelabel.task.InstanceSegmentation"
19 | ],
20 | "5": [
21 | "keypoint_detection",
22 | "paddlelabel.task.BaseTask"
23 | ],
24 | "6": [
25 | "remote_sensing",
26 | "paddlelabel.task.BaseTask"
27 | ],
28 | "7": [
29 | "optical_character_recognition",
30 | "paddlelabel.task.OpticalCharacterRecognition"
31 | ],
32 | "8": [
33 | "point",
34 | "paddlelabel.task.Point"
35 | ]
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/paddlelabel/io/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/io/__init__.py
--------------------------------------------------------------------------------
/paddlelabel/io/image.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import annotations
3 | from pathlib import Path
4 |
5 | from PIL import Image
6 |
7 |
8 | def getSize(img_path: Path) -> tuple[str, int, int]:
9 | im = Image.open(img_path)
10 | width, height = im.size
11 | s = ",".join(map(str, (1,) + (height, width)))
12 | return s, height, width
13 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/classification/multiClass/labels.txt:
--------------------------------------------------------------------------------
1 | red
2 | gray
3 | blue
4 | yellow
5 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/classification/multiClass/test_list.txt:
--------------------------------------------------------------------------------
1 | image/3.jpeg 0 1 2
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/classification/multiClass/train_list.txt:
--------------------------------------------------------------------------------
1 | image/1.jpeg 0
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/classification/multiClass/val_list.txt:
--------------------------------------------------------------------------------
1 | image/2.jpeg 0 1
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/classification/singleClass/labels.txt:
--------------------------------------------------------------------------------
1 | 1只熊
2 | 2只熊
3 | 3只熊
4 | 4只熊
5 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/classification/singleClass/test_list.txt:
--------------------------------------------------------------------------------
1 | 3只熊/3.jpeg 2
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/classification/singleClass/train_list.txt:
--------------------------------------------------------------------------------
1 | 1只熊/1.jpeg 0
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/classification/singleClass/val_list.txt:
--------------------------------------------------------------------------------
1 | 2只熊/2.jpeg 1
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/detection/coco/test.json:
--------------------------------------------------------------------------------
1 | {
2 | "annotations": [
3 | {
4 | "area": 51939.0,
5 | "bbox": [
6 | 252.0,
7 | 387.0,
8 | 261.0,
9 | 199.0
10 | ],
11 | "category_id": 1,
12 | "id": 1,
13 | "image_id": 1,
14 | "iscrowd": 0,
15 | "segmentation": [
16 | []
17 | ]
18 | }
19 | ],
20 | "categories": [
21 | {
22 | "color": "#FF0000",
23 | "id": 1,
24 | "name": "xiaoduxiong",
25 | "supercategory": "toy"
26 | },
27 | {
28 | "color": "#00FF00",
29 | "id": 2,
30 | "name": "toy",
31 | "supercategory": "none"
32 | }
33 | ],
34 | "images": [
35 | {
36 | "coco_url": "",
37 | "date_captured": "",
38 | "file_name": "JPEGImages/1.jpeg",
39 | "flickr_url": "",
40 | "height": 1008,
41 | "id": 1,
42 | "license": "",
43 | "width": 756
44 | }
45 | ],
46 | "info": "",
47 | "licenses": []
48 | }
49 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/detection/coco/train.json:
--------------------------------------------------------------------------------
1 | {
2 | "annotations": [
3 | {
4 | "area": 41940.0,
5 | "bbox": [
6 | 366.0,
7 | 243.0,
8 | 180.0,
9 | 233.0
10 | ],
11 | "category_id": 1,
12 | "id": 2,
13 | "image_id": 2,
14 | "iscrowd": 0,
15 | "segmentation": [
16 | []
17 | ]
18 | },
19 | {
20 | "area": 43930.0,
21 | "bbox": [
22 | 219.0,
23 | 526.0,
24 | 230.0,
25 | 191.0
26 | ],
27 | "category_id": 1,
28 | "id": 3,
29 | "image_id": 2,
30 | "iscrowd": 0,
31 | "segmentation": [
32 | []
33 | ]
34 | }
35 | ],
36 | "categories": [
37 | {
38 | "color": "#FF0000",
39 | "id": 1,
40 | "name": "xiaoduxiong",
41 | "supercategory": "toy"
42 | },
43 | {
44 | "color": "#00FF00",
45 | "id": 2,
46 | "name": "toy",
47 | "supercategory": "none"
48 | }
49 | ],
50 | "images": [
51 | {
52 | "coco_url": "",
53 | "date_captured": "",
54 | "file_name": "JPEGImages/2.jpeg",
55 | "flickr_url": "",
56 | "height": 1008,
57 | "id": 2,
58 | "license": "",
59 | "width": 756
60 | }
61 | ],
62 | "info": "",
63 | "licenses": []
64 | }
65 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/detection/coco/val.json:
--------------------------------------------------------------------------------
1 | {
2 | "annotations": [
3 | {
4 | "area": 43120.0,
5 | "bbox": [
6 | 212.0,
7 | 250.0,
8 | 245.0,
9 | 176.0
10 | ],
11 | "category_id": 1,
12 | "id": 4,
13 | "image_id": 3,
14 | "iscrowd": 0,
15 | "segmentation": [
16 | []
17 | ]
18 | },
19 | {
20 | "area": 37422.0,
21 | "bbox": [
22 | 224.0,
23 | 448.0,
24 | 231.0,
25 | 162.0
26 | ],
27 | "category_id": 1,
28 | "id": 5,
29 | "image_id": 3,
30 | "iscrowd": 0,
31 | "segmentation": [
32 | []
33 | ]
34 | },
35 | {
36 | "area": 37518.0,
37 | "bbox": [
38 | 236.0,
39 | 630.0,
40 | 222.0,
41 | 169.0
42 | ],
43 | "category_id": 1,
44 | "id": 6,
45 | "image_id": 3,
46 | "iscrowd": 0,
47 | "segmentation": [
48 | []
49 | ]
50 | }
51 | ],
52 | "categories": [
53 | {
54 | "color": "#FF0000",
55 | "id": 1,
56 | "name": "xiaoduxiong",
57 | "supercategory": "toy"
58 | },
59 | {
60 | "color": "#00FF00",
61 | "id": 2,
62 | "name": "toy",
63 | "supercategory": "none"
64 | }
65 | ],
66 | "images": [
67 | {
68 | "coco_url": "",
69 | "date_captured": "",
70 | "file_name": "JPEGImages/3.jpeg",
71 | "flickr_url": "",
72 | "height": 1008,
73 | "id": 3,
74 | "license": "",
75 | "width": 756
76 | }
77 | ],
78 | "info": "",
79 | "licenses": []
80 | }
81 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/detection/voc/Annotations/1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | JPEGImages
4 | 1.jpeg
5 | 1
6 |
7 | 756
8 | 1008
9 |
10 |
11 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/detection/voc/Annotations/2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | JPEGImages
4 | 2.jpeg
5 | 2
6 |
7 | 756
8 | 1008
9 |
10 |
11 |
20 |
21 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/detection/voc/Annotations/3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | JPEGImages
4 | 3.jpeg
5 | 3
6 |
7 | 756
8 | 1008
9 |
10 |
11 |
20 |
21 |
30 |
31 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/detection/voc/labels.txt:
--------------------------------------------------------------------------------
1 | bear
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/detection/voc/test_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/1.jpeg Annotations/1.xml
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/detection/voc/train_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/2.jpeg Annotations/2.xml
2 | JPEGImages/4.jpeg Annotations/4.xml
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/detection/voc/val_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/3.jpeg Annotations/3.xml
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/detection/yolo/Annotations/1.txt:
--------------------------------------------------------------------------------
1 | 0 0.5059523809523809 0.48263888888888884 0.34523809523809523 0.1974206349206349
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/detection/yolo/Annotations/2.txt:
--------------------------------------------------------------------------------
1 | 0 0.6031746031746031 0.35664682539682535 0.23809523809523808 0.23115079365079366
2 | 0 0.44179894179894175 0.6165674603174603 0.30423280423280424 0.18948412698412698
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/detection/yolo/Annotations/3.txt:
--------------------------------------------------------------------------------
1 | 0 0.4424603174603175 0.33531746031746035 0.32407407407407407 0.1746031746031746
2 | 0 0.44907407407407407 0.5248015873015873 0.3055555555555556 0.16071428571428573
3 | 0 0.45899470899470907 0.7088293650793651 0.29365079365079366 0.16765873015873015
4 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/detection/yolo/classes.names:
--------------------------------------------------------------------------------
1 | xiaoduxiong
2 | toy
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/detection/yolo/test_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/1.jpeg Annotations/1.txt
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/detection/yolo/train_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/2.jpeg Annotations/2.txt
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/detection/yolo/val_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/3.jpeg Annotations/3.txt
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/img/05.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/bear/img/05.jpg
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/img/06.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/bear/img/06.jpg
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/img/07.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/bear/img/07.jpg
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/img/08.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/bear/img/08.jpg
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/img/09.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/bear/img/09.jpg
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/img/1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/bear/img/1.jpeg
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/img/10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/bear/img/10.jpg
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/img/11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/bear/img/11.png
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/img/2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/bear/img/2.jpeg
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/img/3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/bear/img/3.jpeg
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/img/4.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/bear/img/4.jpeg
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/instanceSegmentation/coco/val.json:
--------------------------------------------------------------------------------
1 | {
2 | "annotations": [
3 | {
4 | "area": 30124.5,
5 | "bbox": [
6 | 258.0,
7 | 403.0,
8 | 250.0,
9 | 176.0
10 | ],
11 | "category_id": 1,
12 | "id": 10,
13 | "image_id": 4,
14 | "iscrowd": 0,
15 | "segmentation": [
16 | [
17 | 481.0,
18 | 439.0,
19 | 501.0,
20 | 486.0,
21 | 495.0,
22 | 527.0,
23 | 508.0,
24 | 552.0,
25 | 487.0,
26 | 569.0,
27 | 470.0,
28 | 560.0,
29 | 429.0,
30 | 579.0,
31 | 388.0,
32 | 575.0,
33 | 365.0,
34 | 552.0,
35 | 333.0,
36 | 569.0,
37 | 318.0,
38 | 554.0,
39 | 310.0,
40 | 549.0,
41 | 294.0,
42 | 552.0,
43 | 270.0,
44 | 554.0,
45 | 261.0,
46 | 527.0,
47 | 286.0,
48 | 515.0,
49 | 259.0,
50 | 509.0,
51 | 258.0,
52 | 480.0,
53 | 277.0,
54 | 476.0,
55 | 297.0,
56 | 475.0,
57 | 297.0,
58 | 452.0,
59 | 322.0,
60 | 450.0,
61 | 349.0,
62 | 458.0,
63 | 368.0,
64 | 425.0,
65 | 411.0,
66 | 408.0,
67 | 449.0,
68 | 415.0,
69 | 469.0,
70 | 403.0,
71 | 482.0,
72 | 410.0,
73 | 489.0,
74 | 420.0
75 | ]
76 | ]
77 | }
78 | ],
79 | "categories": [
80 | {
81 | "color": "#05AF56",
82 | "id": 1,
83 | "name": "xiaoduxiong",
84 | "supercategory": "toy"
85 | },
86 | {
87 | "color": "#64F3BE",
88 | "id": 2,
89 | "name": "toy",
90 | "supercategory": "none"
91 | }
92 | ],
93 | "images": [
94 | {
95 | "coco_url": "",
96 | "date_captured": "",
97 | "file_name": "image/1.jpeg",
98 | "flickr_url": "",
99 | "height": 1008,
100 | "id": 4,
101 | "license": "",
102 | "width": 756
103 | }
104 | ],
105 | "info": "",
106 | "licenses": []
107 | }
108 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/instanceSegmentation/mask/Annotations/1.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/bear/instanceSegmentation/mask/Annotations/1.tiff
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/instanceSegmentation/mask/Annotations/2.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/bear/instanceSegmentation/mask/Annotations/2.tiff
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/instanceSegmentation/mask/Annotations/3.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/bear/instanceSegmentation/mask/Annotations/3.tiff
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/instanceSegmentation/mask/labels.txt:
--------------------------------------------------------------------------------
1 | background
2 | xiaoduxiong
3 | toy
4 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/instanceSegmentation/mask/test_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/4.jpeg Annotations/4.tiff
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/instanceSegmentation/mask/train_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/3.jpeg Annotations/3.tiff
2 | JPEGImages/2.jpeg Annotations/2.tiff
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/instanceSegmentation/mask/val_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/1.jpeg Annotations/1.tiff
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/placeholder/labels.txt:
--------------------------------------------------------------------------------
1 | 1
2 | 2
3 | 3
4 | 4
5 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/placeholder/test_list.txt:
--------------------------------------------------------------------------------
1 | 2/2.jpeg 1
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/placeholder/train_list.txt:
--------------------------------------------------------------------------------
1 | 1/1.jpeg 0
2 | 3/3.jpeg 2
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/placeholder/val_list.txt:
--------------------------------------------------------------------------------
1 | 4/4.jpeg 3
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/point/labelme/Annotations/1.json:
--------------------------------------------------------------------------------
1 | {
2 | "flags": {},
3 | "imageHeight": 1008,
4 | "imagePath": "../JPEGImages/1.jpeg",
5 | "imageWidth": 756,
6 | "shapes": [
7 | {
8 | "flags": {},
9 | "group_id": null,
10 | "label": "ear",
11 | "points": [
12 | [
13 | 471,
14 | 418
15 | ]
16 | ],
17 | "shape_type": "point"
18 | },
19 | {
20 | "flags": {},
21 | "group_id": null,
22 | "label": "ear",
23 | "points": [
24 | [
25 | 482,
26 | 551
27 | ]
28 | ],
29 | "shape_type": "point"
30 | },
31 | {
32 | "flags": {},
33 | "group_id": null,
34 | "label": "hand",
35 | "points": [
36 | [
37 | 311,
38 | 461
39 | ]
40 | ],
41 | "shape_type": "point"
42 | },
43 | {
44 | "flags": {},
45 | "group_id": null,
46 | "label": "hand",
47 | "points": [
48 | [
49 | 339,
50 | 552
51 | ]
52 | ],
53 | "shape_type": "point"
54 | },
55 | {
56 | "flags": {},
57 | "group_id": null,
58 | "label": "foot",
59 | "points": [
60 | [
61 | 267,
62 | 497
63 | ]
64 | ],
65 | "shape_type": "point"
66 | },
67 | {
68 | "flags": {},
69 | "group_id": null,
70 | "label": "foot",
71 | "points": [
72 | [
73 | 275,
74 | 537
75 | ]
76 | ],
77 | "shape_type": "point"
78 | }
79 | ],
80 | "version": "5.1.1"
81 | }
82 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/point/labelme/Annotations/2.json:
--------------------------------------------------------------------------------
1 | {
2 | "flags": {},
3 | "imageHeight": 1008,
4 | "imagePath": "../JPEGImages/2.jpeG",
5 | "imageWidth": 756,
6 | "shapes": [
7 | {
8 | "flags": {},
9 | "group_id": null,
10 | "label": "ear",
11 | "points": [
12 | [
13 | 384,
14 | 312
15 | ]
16 | ],
17 | "shape_type": "point"
18 | },
19 | {
20 | "flags": {},
21 | "group_id": null,
22 | "label": "ear",
23 | "points": [
24 | [
25 | 488,
26 | 258
27 | ]
28 | ],
29 | "shape_type": "point"
30 | },
31 | {
32 | "flags": {},
33 | "group_id": null,
34 | "label": "hand",
35 | "points": [
36 | [
37 | 460,
38 | 437
39 | ]
40 | ],
41 | "shape_type": "point"
42 | },
43 | {
44 | "flags": {},
45 | "group_id": null,
46 | "label": "hand",
47 | "points": [
48 | [
49 | 525,
50 | 393
51 | ]
52 | ],
53 | "shape_type": "point"
54 | },
55 | {
56 | "flags": {},
57 | "group_id": null,
58 | "label": "foot",
59 | "points": [
60 | [
61 | 497,
62 | 465
63 | ]
64 | ],
65 | "shape_type": "point"
66 | },
67 | {
68 | "flags": {},
69 | "group_id": null,
70 | "label": "foot",
71 | "points": [
72 | [
73 | 525,
74 | 449
75 | ]
76 | ],
77 | "shape_type": "point"
78 | },
79 | {
80 | "flags": {},
81 | "group_id": null,
82 | "label": "foot",
83 | "points": [
84 | [
85 | 236,
86 | 654
87 | ]
88 | ],
89 | "shape_type": "point"
90 | },
91 | {
92 | "flags": {},
93 | "group_id": null,
94 | "label": "foot",
95 | "points": [
96 | [
97 | 256,
98 | 692
99 | ]
100 | ],
101 | "shape_type": "point"
102 | },
103 | {
104 | "flags": {},
105 | "group_id": null,
106 | "label": "hand",
107 | "points": [
108 | [
109 | 307,
110 | 692
111 | ]
112 | ],
113 | "shape_type": "point"
114 | },
115 | {
116 | "flags": {},
117 | "group_id": null,
118 | "label": "hand",
119 | "points": [
120 | [
121 | 264,
122 | 638
123 | ]
124 | ],
125 | "shape_type": "point"
126 | },
127 | {
128 | "flags": {},
129 | "group_id": null,
130 | "label": "ear",
131 | "points": [
132 | [
133 | 384,
134 | 556
135 | ]
136 | ],
137 | "shape_type": "point"
138 | },
139 | {
140 | "flags": {},
141 | "group_id": null,
142 | "label": "ear",
143 | "points": [
144 | [
145 | 428,
146 | 658
147 | ]
148 | ],
149 | "shape_type": "point"
150 | }
151 | ],
152 | "version": "5.1.1"
153 | }
154 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/semanticSegmentation/coco/val.json:
--------------------------------------------------------------------------------
1 | {
2 | "annotations": [
3 | {
4 | "area": 30124.5,
5 | "bbox": [
6 | 258.0,
7 | 403.0,
8 | 250.0,
9 | 176.0
10 | ],
11 | "category_id": 1,
12 | "id": 10,
13 | "image_id": 4,
14 | "iscrowd": 0,
15 | "segmentation": [
16 | [
17 | 481.0,
18 | 439.0,
19 | 501.0,
20 | 486.0,
21 | 495.0,
22 | 527.0,
23 | 508.0,
24 | 552.0,
25 | 487.0,
26 | 569.0,
27 | 470.0,
28 | 560.0,
29 | 429.0,
30 | 579.0,
31 | 388.0,
32 | 575.0,
33 | 365.0,
34 | 552.0,
35 | 333.0,
36 | 569.0,
37 | 318.0,
38 | 554.0,
39 | 310.0,
40 | 549.0,
41 | 294.0,
42 | 552.0,
43 | 270.0,
44 | 554.0,
45 | 261.0,
46 | 527.0,
47 | 286.0,
48 | 515.0,
49 | 259.0,
50 | 509.0,
51 | 258.0,
52 | 480.0,
53 | 277.0,
54 | 476.0,
55 | 297.0,
56 | 475.0,
57 | 297.0,
58 | 452.0,
59 | 322.0,
60 | 450.0,
61 | 349.0,
62 | 458.0,
63 | 368.0,
64 | 425.0,
65 | 411.0,
66 | 408.0,
67 | 449.0,
68 | 415.0,
69 | 469.0,
70 | 403.0,
71 | 482.0,
72 | 410.0,
73 | 489.0,
74 | 420.0
75 | ]
76 | ]
77 | }
78 | ],
79 | "categories": [
80 | {
81 | "color": "#05AF56",
82 | "id": 1,
83 | "name": "xiaoduxiong",
84 | "supercategory": "toy"
85 | },
86 | {
87 | "color": "#64F3BE",
88 | "id": 2,
89 | "name": "toy",
90 | "supercategory": "none"
91 | }
92 | ],
93 | "images": [
94 | {
95 | "coco_url": "",
96 | "date_captured": "",
97 | "file_name": "image/1.jpeg",
98 | "flickr_url": "",
99 | "height": 1008,
100 | "id": 4,
101 | "license": "",
102 | "width": 756
103 | }
104 | ],
105 | "info": "",
106 | "licenses": []
107 | }
108 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/semanticSegmentation/mask/Annotations/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/bear/semanticSegmentation/mask/Annotations/1.png
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/semanticSegmentation/mask/Annotations/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/bear/semanticSegmentation/mask/Annotations/2.png
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/semanticSegmentation/mask/Annotations/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/bear/semanticSegmentation/mask/Annotations/3.png
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/semanticSegmentation/mask/labels.txt:
--------------------------------------------------------------------------------
1 | background
2 | xiaoduxiong
3 | toy
4 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/semanticSegmentation/mask/test_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/4.jpeg Annotations/4.png
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/semanticSegmentation/mask/train_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/3.jpeg Annotations/3.png
2 | JPEGImages/2.jpeg Annotations/2.png
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/bear/semanticSegmentation/mask/val_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/1.jpeg Annotations/1.png
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/classification/multiClass/labels.txt:
--------------------------------------------------------------------------------
1 | 梨
2 | 苹果
3 | 1
4 | 2
5 | 4
6 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/classification/multiClass/test_list.txt:
--------------------------------------------------------------------------------
1 | image/1.jpeg 1 2
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/classification/multiClass/train_list.txt:
--------------------------------------------------------------------------------
1 | image/3.jpeg 1 3
2 | image/4.jpeg 0 4
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/classification/multiClass/val_list.txt:
--------------------------------------------------------------------------------
1 | image/2.jpeg 0 3
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/classification/singleClass/labels.txt:
--------------------------------------------------------------------------------
1 | 苹果
2 | 梨
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/classification/singleClass/paddlelabel.warning:
--------------------------------------------------------------------------------
1 | PP Label is using files stored under this folder!
2 | Changing file in this folder may cause issues.
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/classification/singleClass/test_list.txt:
--------------------------------------------------------------------------------
1 | 梨/2.jpeg 1
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/classification/singleClass/train_list.txt:
--------------------------------------------------------------------------------
1 | 苹果/1.jpeg 0
2 | 苹果/3.jpeg 0
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/classification/singleClass/val_list.txt:
--------------------------------------------------------------------------------
1 | 梨/4.jpeg 1
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/coco/test.json:
--------------------------------------------------------------------------------
1 | {
2 | "annotations": [
3 | {
4 | "area": 137772.0,
5 | "bbox": [
6 | 182.0,
7 | 322.0,
8 | 356.0,
9 | 387.0
10 | ],
11 | "category_id": 2,
12 | "id": 9,
13 | "image_id": 4,
14 | "iscrowd": 0,
15 | "segmentation": [
16 | []
17 | ]
18 | }
19 | ],
20 | "categories": [
21 | {
22 | "color": "#4a90e2",
23 | "id": 1,
24 | "name": "梨",
25 | "supercategory": "none"
26 | },
27 | {
28 | "color": "#008000",
29 | "id": 2,
30 | "name": "苹果",
31 | "supercategory": "none"
32 | }
33 | ],
34 | "images": [
35 | {
36 | "coco_url": "",
37 | "date_captured": "",
38 | "file_name": "image/1.jpeg",
39 | "flickr_url": "",
40 | "height": 1008,
41 | "id": 4,
42 | "license": "",
43 | "width": 756
44 | }
45 | ],
46 | "info": "",
47 | "licenses": []
48 | }
49 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/coco/train.json:
--------------------------------------------------------------------------------
1 | {
2 | "annotations": [
3 | {
4 | "area": 167132.0,
5 | "bbox": [
6 | 100.5,
7 | 233.5,
8 | 329.0,
9 | 508.0
10 | ],
11 | "category_id": 1,
12 | "id": 1,
13 | "image_id": 1,
14 | "iscrowd": 0,
15 | "segmentation": [
16 | []
17 | ]
18 | },
19 | {
20 | "area": 71214.0,
21 | "bbox": [
22 | 360.0,
23 | 391.0,
24 | 249.0,
25 | 286.0
26 | ],
27 | "category_id": 1,
28 | "id": 2,
29 | "image_id": 1,
30 | "iscrowd": 0,
31 | "segmentation": [
32 | []
33 | ]
34 | },
35 | {
36 | "area": 41790.0,
37 | "bbox": [
38 | 243.0,
39 | 269.0,
40 | 210.0,
41 | 199.0
42 | ],
43 | "category_id": 1,
44 | "id": 3,
45 | "image_id": 2,
46 | "iscrowd": 0,
47 | "segmentation": [
48 | []
49 | ]
50 | },
51 | {
52 | "area": 47260.0,
53 | "bbox": [
54 | 159.5,
55 | 380.5,
56 | 170.0,
57 | 278.0
58 | ],
59 | "category_id": 1,
60 | "id": 4,
61 | "image_id": 2,
62 | "iscrowd": 0,
63 | "segmentation": [
64 | []
65 | ]
66 | },
67 | {
68 | "area": 75504.0,
69 | "bbox": [
70 | 276.0,
71 | 367.0,
72 | 242.0,
73 | 312.0
74 | ],
75 | "category_id": 1,
76 | "id": 5,
77 | "image_id": 2,
78 | "iscrowd": 0,
79 | "segmentation": [
80 | []
81 | ]
82 | },
83 | {
84 | "area": 42250.0,
85 | "bbox": [
86 | 425.0,
87 | 381.0,
88 | 169.0,
89 | 250.0
90 | ],
91 | "category_id": 1,
92 | "id": 6,
93 | "image_id": 2,
94 | "iscrowd": 0,
95 | "segmentation": [
96 | []
97 | ]
98 | }
99 | ],
100 | "categories": [
101 | {
102 | "color": "#4a90e2",
103 | "id": 1,
104 | "name": "梨",
105 | "supercategory": "none"
106 | },
107 | {
108 | "color": "#008000",
109 | "id": 2,
110 | "name": "苹果",
111 | "supercategory": "none"
112 | }
113 | ],
114 | "images": [
115 | {
116 | "coco_url": "",
117 | "date_captured": "",
118 | "file_name": "image/2.jpeg",
119 | "flickr_url": "",
120 | "height": 1008,
121 | "id": 1,
122 | "license": "",
123 | "width": 756
124 | },
125 | {
126 | "coco_url": "",
127 | "date_captured": "",
128 | "file_name": "image/4.jpeg",
129 | "flickr_url": "",
130 | "height": 1008,
131 | "id": 2,
132 | "license": "",
133 | "width": 756
134 | }
135 | ],
136 | "info": "",
137 | "licenses": []
138 | }
139 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/coco/val.json:
--------------------------------------------------------------------------------
1 | {
2 | "annotations": [
3 | {
4 | "area": 254241.0,
5 | "bbox": [
6 | -76.0,
7 | 267.0,
8 | 477.0,
9 | 533.0
10 | ],
11 | "category_id": 2,
12 | "id": 7,
13 | "image_id": 3,
14 | "iscrowd": 0,
15 | "segmentation": [
16 | []
17 | ]
18 | },
19 | {
20 | "area": 227700.0,
21 | "bbox": [
22 | 407.0,
23 | 294.0,
24 | 460.0,
25 | 495.0
26 | ],
27 | "category_id": 2,
28 | "id": 8,
29 | "image_id": 3,
30 | "iscrowd": 0,
31 | "segmentation": [
32 | []
33 | ]
34 | }
35 | ],
36 | "categories": [
37 | {
38 | "color": "#4a90e2",
39 | "id": 1,
40 | "name": "梨",
41 | "supercategory": "none"
42 | },
43 | {
44 | "color": "#008000",
45 | "id": 2,
46 | "name": "苹果",
47 | "supercategory": "none"
48 | }
49 | ],
50 | "images": [
51 | {
52 | "coco_url": "",
53 | "date_captured": "",
54 | "file_name": "image/3.jpeg",
55 | "flickr_url": "",
56 | "height": 1008,
57 | "id": 3,
58 | "license": "",
59 | "width": 756
60 | }
61 | ],
62 | "info": "",
63 | "licenses": []
64 | }
65 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/voc/Annotations/1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | JPEGImages
4 | 1.jpeg
5 | 1
6 |
7 | 756
8 | 1008
9 |
10 |
11 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/voc/Annotations/2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | JPEGImages
4 | 2.jpeg
5 | 2
6 |
7 | 756
8 | 1008
9 |
10 |
11 |
20 |
21 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/voc/Annotations/3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | JPEGImages
4 | 3.jpeg
5 | 2
6 |
7 | 756
8 | 1008
9 |
10 |
11 |
20 |
21 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/voc/Annotations/4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | JPEGImages
4 | 4.jpeg
5 | 4
6 |
7 | 756
8 | 1008
9 |
10 |
11 |
20 |
21 |
30 |
31 |
40 |
41 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/voc/labels.txt:
--------------------------------------------------------------------------------
1 | 梨
2 | 苹果
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/voc/test_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/1.jpeg Annotations/1.xml
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/voc/train_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/2.jpeg Annotations/2.xml
2 | JPEGImages/4.jpeg Annotations/4.xml
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/voc/val_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/3.jpeg Annotations/3.xml
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/yolo/Annotations/1.txt:
--------------------------------------------------------------------------------
1 | 1 0.46296296296296297 0.5264367816091954 0.7325102880658436 0.8896551724137931
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/yolo/Annotations/2.txt:
--------------------------------------------------------------------------------
1 | 0 0.32265625 0.47012302284710017 0.5140625 0.8927943760984183
2 | 0 0.66640625 0.5527240773286468 0.3890625 0.5026362038664324
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/yolo/Annotations/3.txt:
--------------------------------------------------------------------------------
1 | 1 0.3040909090909091 0.5400815217391304 0.43363636363636365 0.7241847826086957
2 | 1 0.7354545454545455 0.5509510869565217 0.41818181818181815 0.6725543478260869
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/yolo/Annotations/4.txt:
--------------------------------------------------------------------------------
1 | 0 0.43999999999999995 0.22900000000000004 0.42 0.398
2 | 0 0.232 0.53 0.34 0.556
3 | 0 0.538 0.538 0.484 0.624
4 | 0 0.763 0.504 0.338 0.5
5 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/yolo/classes.names:
--------------------------------------------------------------------------------
1 | 梨
2 | 苹果
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/yolo/test_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/1.jpeg Annotations/1.txt
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/yolo/train_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/2.jpeg Annotations/2.txt
2 | JPEGImages/4.jpeg Annotations/4.txt
3 | JPEGImages/5.jpeg Annotations/5.txt
4 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/detection/yolo/val_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/3.jpeg Annotations/3.txt
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/img/1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/fruit/img/1.jpeg
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/img/2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/fruit/img/2.jpeg
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/img/3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/fruit/img/3.jpeg
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/img/4.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/fruit/img/4.jpeg
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/img/5.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/fruit/img/5.jpeg
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/instanceSegmentation/mask/Annotations/1.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/fruit/instanceSegmentation/mask/Annotations/1.tiff
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/instanceSegmentation/mask/Annotations/2.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/fruit/instanceSegmentation/mask/Annotations/2.tiff
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/instanceSegmentation/mask/Annotations/3.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/fruit/instanceSegmentation/mask/Annotations/3.tiff
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/instanceSegmentation/mask/Annotations/4.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/fruit/instanceSegmentation/mask/Annotations/4.tiff
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/instanceSegmentation/mask/labels.txt:
--------------------------------------------------------------------------------
1 | background
2 | 苹果 1
3 | 梨 2
4 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/instanceSegmentation/mask/test_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/4.jpeg Annotations/4.tiff
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/instanceSegmentation/mask/train_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/2.jpeg Annotations/2.tiff
2 | JPEGImages/3.jpeg Annotations/3.tiff
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/instanceSegmentation/mask/val_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/1.jpeg Annotations/1.tiff
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/placeholder/labels.txt:
--------------------------------------------------------------------------------
1 | 苹果
2 | 梨
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/placeholder/paddlelabel.warning:
--------------------------------------------------------------------------------
1 | PP Label is using files stored under this folder!
2 | Changing file in this folder may cause issues.
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/placeholder/test_list.txt:
--------------------------------------------------------------------------------
1 | 梨/2.jpeg 1
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/placeholder/train_list.txt:
--------------------------------------------------------------------------------
1 | 苹果/1.jpeg 0
2 | 苹果/3.jpeg 0
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/placeholder/val_list.txt:
--------------------------------------------------------------------------------
1 | 梨/4.jpeg 1
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/semanticSegmentation/mask/Annotations/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/fruit/semanticSegmentation/mask/Annotations/1.png
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/semanticSegmentation/mask/Annotations/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/fruit/semanticSegmentation/mask/Annotations/2.png
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/semanticSegmentation/mask/Annotations/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/fruit/semanticSegmentation/mask/Annotations/3.png
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/semanticSegmentation/mask/Annotations/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/paddlelabel/sample/fruit/semanticSegmentation/mask/Annotations/4.png
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/semanticSegmentation/mask/labels.txt:
--------------------------------------------------------------------------------
1 | background
2 | 梨 - 0 128 0
3 | 苹果 - 74 144 226
4 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/semanticSegmentation/mask/test_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/4.jpeg Annotations/4.png
2 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/semanticSegmentation/mask/train_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/2.jpeg Annotations/2.png
2 | JPEGImages/3.jpeg Annotations/3.png
3 |
--------------------------------------------------------------------------------
/paddlelabel/sample/fruit/semanticSegmentation/mask/val_list.txt:
--------------------------------------------------------------------------------
1 | JPEGImages/1.jpeg Annotations/1.png
2 |
--------------------------------------------------------------------------------
/paddlelabel/serve.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from pathlib import Path
3 | import shutil
4 | import logging
5 |
6 | from flask_cors import CORS # TODO: custom middleware, dont use this package
7 | import alembic
8 | from alembic.config import Config
9 | from alembic.script import ScriptDirectory
10 |
11 | from paddlelabel import configs
12 | from paddlelabel.util import Resolver, backend_error
13 | from paddlelabel.config import connexion_app
14 | from paddlelabel.api.controller.setting import init_site_settings
15 | from paddlelabel.api.model import AlembicVersion
16 |
17 | HERE = Path(__file__).parent.absolute()
18 | logger = logging.getLogger("paddlelabel")
19 |
20 | # 1. static routes
21 | @connexion_app.app.route("/")
22 | def index():
23 | return "", 301, {"Location": "/static/index.html"}
24 |
25 |
26 | @connexion_app.app.route("/static/doc/")
27 | def doc_index():
28 | return "", 301, {"Location": "/static/doc/index.html"}
29 |
30 |
31 | @connexion_app.app.route("/static/doc/CN/")
32 | def cn_doc_index():
33 | return "", 301, {"Location": "/static/doc/CN/index.html"}
34 |
35 |
36 | @connexion_app.app.route("/static/doc/EN/")
37 | def en_doc_index():
38 | return "", 301, {"Location": "/static/doc/EN/index.html"}
39 |
40 |
41 | # 2. update db version
42 | db_exists = configs.db_path.exists()
43 | alembic_cfg = alembic.config.Config(HERE / "alembic.ini")
44 | alembic_cfg.set_main_option("script_location", str(HERE / "dbmigration"))
45 | alembic_cfg.set_main_option("sqlalchemy.url", configs.db_url)
46 | # Create the alembic version table if it doesn’t exist already
47 | alembic.command.ensure_version(alembic_cfg)
48 |
49 | with connexion_app.app.app_context():
50 | res = AlembicVersion.query.all()
51 | # get version in db
52 | curr_db_v = None if len(res) == 0 else res[0].version_num
53 | # get version of revision head
54 | script = ScriptDirectory.from_config(alembic_cfg)
55 | heads = script.get_revisions("heads")
56 | db_head_version = heads[0].revision
57 |
58 | # v0.1.0: db exists but doesn't have version
59 | if curr_db_v is None and db_exists:
60 | alembic.command.stamp(alembic_cfg, revision="23c1bf9b7f48")
61 |
62 | # need db backup
63 | if curr_db_v != db_head_version and db_exists:
64 | from datetime import datetime
65 |
66 | back_up_path = (
67 | Path(configs.db_path).parent
68 | / f"{str(datetime.now()).split('.')[0].replace(' ', '_').replace(':', '_')}-paddlelabel.db.bk"
69 | )
70 | shutil.copy(Path(configs.db_path), back_up_path)
71 | logger.warn(
72 | f"Performing database update. Should anything goes wrong during this update, you can find the old database at {str(back_up_path)}"
73 | )
74 |
75 | # perform db upgrade
76 | alembic.command.upgrade(alembic_cfg, "head")
77 |
78 | # TODO: move this to be managed by alembic @lin
79 | init_site_settings(HERE / "default_setting.json")
80 |
81 | if configs.debug:
82 | alembic.command.check(alembic_cfg) # abort when model definition is changed and a new reversion is required
83 |
84 | logger.setLevel(configs.log_level)
85 |
86 | # 3. serve the app
87 | connexion_app.add_api(
88 | HERE / "openapi.yml",
89 | resolver=Resolver("paddlelabel.api", collection_endpoint_name="get_all"),
90 | # request with undefined param returns error, dont enforce body
91 | strict_validation=True,
92 | pythonic_params=True,
93 | options={"swagger_ui": configs.debug},
94 | )
95 | connexion_app.add_error_handler(Exception, backend_error)
96 |
97 | # TODO: use middleware, instead of flask-cors
98 | CORS(connexion_app.app)
99 |
--------------------------------------------------------------------------------
/paddlelabel/task/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from .base import BaseTask
3 | from .classification import Classification
4 | from .detection import Detection
5 | from .semantic_segmentation import SemanticSegmentation
6 | from .instance_segmentation import InstanceSegmentation
7 | from .optical_character_recognition import OpticalCharacterRecognition
8 | from .point import Point
9 |
--------------------------------------------------------------------------------
/paddlelabel/task/point.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import annotations
3 |
4 | from pathlib import Path
5 | import shutil
6 |
7 | from paddlelabel.task.util.labelme import get_matching, parse_ann, write_ann
8 | from paddlelabel.api import Task
9 | from paddlelabel.task.base import BaseTask
10 | from paddlelabel.io.image import getSize
11 |
12 |
13 | class Point(BaseTask):
14 | def __init__(self, project, data_dir: Path | None = None, is_export=False):
15 | super(Point, self).__init__(project, data_dir=data_dir, skip_label_import=True, is_export=is_export)
16 | self.importers = {
17 | "labelme": self.labelme_importer,
18 | }
19 | self.exporters = {
20 | "labelme": self.labelme_exporter,
21 | }
22 |
23 | def labelme_importer(self, data_dir: Path):
24 | # 1. set params
25 | data_dir = Path(data_dir)
26 | self.create_warning(data_dir)
27 |
28 | # 2. import all datas
29 | for img_path, (ann_path, set_idx) in get_matching(data_dir).items():
30 | if ann_path is not None:
31 | height, width, anns = parse_ann(ann_path, set(["point"]))
32 | size = f"1,{height},{width}"
33 | else:
34 | anns = []
35 | size, _, _ = getSize(img_path)
36 | self.add_task([{"path": str(img_path), "size": size}], [anns], set_idx)
37 |
38 | self.commit()
39 |
40 | def labelme_exporter(self, export_dir: Path):
41 | # 1. set params, prep output folders
42 | project = self.project
43 |
44 | export_dir = Path(export_dir)
45 | export_dir.mkdir(exist_ok=True, parents=True)
46 | img_dst = export_dir / "JPEGImages"
47 | ann_dst = export_dir / "Annotations"
48 | img_dst.mkdir()
49 | ann_dst.mkdir()
50 | data_dir = Path(project.data_dir)
51 |
52 | # 2. move images and write ann json
53 | tasks = Task._get(project_id=project.project_id, many=True)
54 | new_paths = []
55 | for task in tasks:
56 | data = task.datas[0]
57 | _, height, width = map(int, data.size.split(","))
58 | img_path = img_dst / Path(data.path).name
59 | ann_path = ann_dst / (Path(data.path).name.split(".")[0] + ".json")
60 | shutil.copy(data_dir / data.path, img_path)
61 | write_ann(ann_path, img_path, height, width, data.annotations, with_data=False)
62 |
63 | new_paths.append([str(img_path.relative_to(export_dir))])
64 | print(new_paths)
65 |
66 | # 3. write split files
67 | self.export_split(export_dir, tasks, new_paths, with_labels=False, annotation_ext=".json")
68 |
--------------------------------------------------------------------------------
/paddlelabel/task/util/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from .file import (
3 | create_dir,
4 | listdir,
5 | copy,
6 | copy_content,
7 | image_extensions,
8 | ensure_unique_base_name,
9 | get_fname,
10 | match_by_base_name,
11 | break_path,
12 | )
13 | from .manager import ComponentManager
14 | from .color import rgb_to_hex, hex_to_rgb, rand_hex_color, name_to_hex
15 |
--------------------------------------------------------------------------------
/paddlelabel/task/util/color.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import random
3 | import time
4 |
5 |
6 | def rgb_to_hex(rgb):
7 | rgb = tuple(int(c) for c in rgb)
8 | return ("#%02x%02x%02x" % rgb).upper()
9 |
10 |
11 | def hex_to_rgb(value):
12 | value = value.lstrip("#")
13 | lv = len(value)
14 | return tuple(int(value[i : i + lv // 3], 16) for i in range(0, lv, lv // 3))
15 |
16 |
17 | def name_to_hex(name):
18 | color_map = {
19 | "red": "#FF0000",
20 | "white": "#FFFFFF",
21 | "cyan": "#00FFFF",
22 | "silver": "#C0C0C0",
23 | "blue": "#0000FF",
24 | "gray": "#808080",
25 | "darkblue": "#0000A0",
26 | "black": "#000000",
27 | "lightblue": "#ADD8E6",
28 | "orange": "#FFA500",
29 | "purple": "#800080",
30 | "brown": "#A52A2A",
31 | "yellow": "#FFFF00",
32 | "maroon": "#800000",
33 | "lime": "#00FF00",
34 | "green": "#008000",
35 | "magenta": "#FF00FF",
36 | "olive": "#808000",
37 | }
38 | if name[0] == "#" and len(name) == 7:
39 | return name
40 |
41 | name = name.lower()
42 | if name not in color_map.keys():
43 | raise RuntimeError(f"Don't have hex value for color {name}")
44 |
45 | return color_map[name]
46 |
47 |
48 | # TODO: generate color with high contrast
49 | # TODO: generate color within certain range
50 | # TODO: even devide color space
51 | def rand_hex_color(current_colors=[]):
52 | random.seed(time.time())
53 | r = lambda: random.randint(0, 255)
54 | while True:
55 | c = "#%02X%02X%02X" % (r(), r(), r())
56 | c = c.upper()
57 | if c not in current_colors:
58 | break
59 | return c
60 |
61 |
62 | # Red #FF0000
63 | # White #FFFFFF
64 | # Cyan #00FFFF
65 | # Silver #C0C0C0
66 | # Blue #0000FF
67 | # Gray #808080
68 | # DarkBlue #0000A0
69 | # Black #000000
70 | # LightBlue #ADD8E6
71 | # Orange #FFA500
72 | # Purple #800080
73 | # Brown #A52A2A
74 | # Yellow #FFFF00
75 | # Maroon #800000
76 | # Lime #00FF00
77 | # Green #008000
78 | # Magenta #FF00FF
79 | # Olive #808000
80 |
--------------------------------------------------------------------------------
/paddlelabel/tool/__main__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from pathlib import Path
3 | import inspect
4 |
5 | from prompt_toolkit.shortcuts import message_dialog, radiolist_dialog, input_dialog
6 | from prompt_toolkit.styles import Style
7 |
8 | from simple_file_format import eiseg_label2_paddlelabel
9 |
10 | HERE = Path("__file__").parent.absolute()
11 | print(HERE)
12 |
13 | # print(inspect.signature(input_dialog))
14 | # exit()
15 |
16 |
17 | def run():
18 | # 0. 使用指南
19 | message_dialog(
20 | title="PaddleLabel Tools Tui 使用指南",
21 | text="""
22 | - 按空格/回车进行选择
23 | - 完成选择/输入后按Tab切换到确定/退出按钮部分
24 | - 按空格/回车进行确定
25 | """,
26 | ).run()
27 |
28 | # 1. 工具选择
29 | result = radiolist_dialog(
30 | title="PaddleLabel Tools Tui",
31 | text="请选择需要使用的工具",
32 | values=[
33 | ("eiseg_label2paddlelabel", "转换EISeg标签列表到PaddleLabel格式"),
34 | ],
35 | ).run()
36 |
37 | # 2.1 eiseg 格式标签列表转 PaddleLabel格式
38 | if result == "eiseg_label2paddlelabel":
39 | pj_category = radiolist_dialog(
40 | title="EISeg标签列表转PaddleLabel格式",
41 | text="请选择标签列表所属项目类型",
42 | values=[
43 | ("detection", "目标检测"),
44 | ("semantic_segmentation", "语义分割"),
45 | ],
46 | ).run()
47 |
48 | eiseg_label_path = None
49 | while eiseg_label_path is None:
50 | eiseg_label_path = input_dialog(
51 | title="EISeg标签列表转PaddleLabel格式",
52 | text=f"""
53 | 请输入EISeg标签列表文件文件路径
54 | - 可以为绝对路径
55 | - 可以为相对 {str(HERE)} 的相对路径
56 | """,
57 | ).run()
58 | eiseg_label_path = Path(eiseg_label_path).absolute()
59 | if not eiseg_label_path.exists():
60 | message_dialog(
61 | title="EISeg标签列表转PaddleLabel格式",
62 | text=f"未能找到 {str(eiseg_label_path)} 文件,请确认文件存在,路径输入正确",
63 | ok_text="重新输入",
64 | ).run()
65 | eiseg_label_path = None
66 | assert eiseg_label_path is not None
67 | eiseg_label2_paddlelabel(
68 | eiseg_label_path,
69 | add_background=pj_category == "semantic_segmentation",
70 | label_id_delta=1,
71 | )
72 |
73 |
74 | if __name__ == "__main__":
75 | run()
76 |
--------------------------------------------------------------------------------
/paddlelabel/tool/simple_file_format.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from pathlib import Path
3 |
4 |
5 | def eiseg_label2_paddlelabel(eiseg_label_path: Path, add_background: bool = False, label_id_delta: int = 0):
6 | # 1. read eiseg label
7 | eiseg_label = eiseg_label_path.read_text(encoding="utf-8").split("\n")
8 | eiseg_label = [l.split(" ") for l in eiseg_label if len(l) != 0]
9 |
10 | # 2.1 split
11 | pdlabel_label = [[l[1], l[0], *l[2:]] for l in eiseg_label]
12 | # # 2.2 change label id
13 | if label_id_delta != 0:
14 | for idx in range(len(pdlabel_label)):
15 | pdlabel_label[idx][1] = str(int(pdlabel_label[idx][1]) + label_id_delta)
16 | # 2.3 join to string
17 | pdlabel_label = [" ".join(l) for l in pdlabel_label]
18 | # 2.4 add background line
19 | pdlabel_label = ["background 0 0 0 0"] + pdlabel_label if add_background else pdlabel_label
20 | # 2.5 join to file
21 | pdlabel_label = "\n".join(pdlabel_label)
22 |
23 | # 3. rename eiseg format file and write pdlabel format file
24 | orig_name = eiseg_label_path.name
25 | name, ext = orig_name.split(".")
26 | eiseg_label_path.rename(eiseg_label_path.parent / f"{name}_eiseg.{ext}")
27 | pdlabel_label_path = eiseg_label_path.parent / orig_name
28 | pdlabel_label_path.write_text(pdlabel_label)
29 |
--------------------------------------------------------------------------------
/paddlelabel/version:
--------------------------------------------------------------------------------
1 | 1.0.5
2 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [tool.black]
2 | line-length = 120
3 | include = '\.pyi?$'
4 | exclude = '''
5 | /(
6 | \.git
7 | | \.hg
8 | | \.mypy_cache
9 | | \.tox
10 | | \.venv
11 | | _build
12 | | buck-out
13 | | build
14 | | dist
15 | )/
16 | '''
17 |
--------------------------------------------------------------------------------
/pyproject.toml.temp:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ["setuptools>=61.0"]
3 | build-backend = "setuptools.build_meta"
4 |
5 | [project]
6 | dynamic = ["readme"]
7 | version = "0.0.30"
8 |
9 | name="paddlelabel",
10 | version=open((HERE / "paddlelabel" / "version"), "r").read().strip(),
11 | authors = [{ name="PaddleCV-SIG", email="me@linhan.email" }]
12 | description="Web Based Multi Purpose Annotation Software",
13 | long_description=README,
14 | long_description_content_type="text/markdown",
15 | url="https://github.com/PaddleCV-SIG/PaddleLabel",
16 | author="PaddleCV-SIG",
17 | author_email="me@linhan.email",
18 | license = { file="LICENSE" }
19 | classifiers=[
20 | "License :: OSI Approved :: Apache Software License",
21 | "Programming Language :: Python :: 3",
22 | "Programming Language :: Python :: 3.9",
23 | ],
24 | requires-python = ">=3.6"
25 | packages=find_packages(exclude=("tool.*", "tool")),
26 | include_package_data=True,
27 | install_requires=REQUIRED_PACKAGES,
28 | entry_points={
29 | "console_scripts": [
30 | "paddlelabel=paddlelabel.__main__:run",
31 | "pdlabel=paddlelabel.__main__:run",
32 | ]
33 | },
34 |
35 | [project]
36 | dynamic = ["dependencies"]
37 | [tool.setuptools.dynamic]
38 | dependencies = {file = ["requirements.txt"]}
39 |
40 | [tool.black]
41 | line-length = 120
42 | include = '\.pyi?$'
43 | exclude = '''
44 | /(
45 | \.git
46 | | \.hg
47 | | \.mypy_cache
48 | | \.tox
49 | | \.venv
50 | | _build
51 | | buck-out
52 | | build
53 | | dist
54 | )/
55 | '''
56 |
--------------------------------------------------------------------------------
/requirements-dev.txt:
--------------------------------------------------------------------------------
1 | connexion[swagger-ui]
2 |
3 | black
4 | pre-commit
5 | jake
6 |
7 | types-Pillow
8 | types-Flask-Cors
9 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | # Web related
2 | connexion
3 | marshmallow_sqlalchemy
4 |
5 | ## currently required, but will be removed in a future version
6 | flask_sqlalchemy
7 | flask_marshmallow
8 | flask_cors
9 |
10 | # Task related
11 | opencv-python
12 | numpy
13 | pycocotoolse
14 | tqdm
15 | tifffile
16 |
17 | # db migration
18 | alembic
19 |
20 | # paddlelabel_tools
21 | prompt_toolkit
22 |
23 | # imagecodecs
24 | # uuid
25 | # jwt
26 | # werkzeug
27 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import pathlib
3 | from setuptools import setup, find_packages, Extension
4 |
5 | HERE = pathlib.Path(__file__).parent
6 |
7 | README = (HERE / "README.md").read_text(encoding="utf-8")
8 |
9 |
10 | with open("requirements.txt", "r") as fin:
11 | REQUIRED_PACKAGES = fin.read()
12 |
13 | setup(
14 | name="paddlelabel",
15 | version=open((HERE / "paddlelabel" / "version"), "r").read().strip(),
16 | description="Web Based Multi Purpose Annotation Software",
17 | long_description=README,
18 | long_description_content_type="text/markdown",
19 | url="https://github.com/PaddleCV-SIG/PaddleLabel",
20 | author="PaddleCV-SIG",
21 | author_email="me@linhan.email",
22 | license="Apache Software License",
23 | classifiers=[
24 | "License :: OSI Approved :: Apache Software License",
25 | "Programming Language :: Python :: 3",
26 | "Programming Language :: Python :: 3.9",
27 | ],
28 | packages=find_packages(exclude=("tool.*", "tool")),
29 | include_package_data=True,
30 | install_requires=REQUIRED_PACKAGES,
31 | entry_points={
32 | "console_scripts": [
33 | "paddlelabel=paddlelabel.__main__:run",
34 | "pdlabel=paddlelabel.__main__:run",
35 | "pt=paddlelabel.tool.__main__:run",
36 | "paddlelabel_tools=paddlelabel.tool.__main__:run",
37 | ]
38 | },
39 | )
40 |
--------------------------------------------------------------------------------
/thunder-tests/thunderActivity.json:
--------------------------------------------------------------------------------
1 | []
2 |
--------------------------------------------------------------------------------
/thunder-tests/thunderCollection.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "_id": "f8fe5699-a721-439d-be48-4d18b9cd9672",
4 | "colName": "project",
5 | "created": "2023-01-28T14:41:00.442Z",
6 | "folders": [
7 | {
8 | "_id": "34a30cd1-b515-4d22-bdd9-52e4b6762385",
9 | "containerId": "",
10 | "created": "2023-01-29T21:32:56.344Z",
11 | "name": "1_Import",
12 | "sortNum": 10000
13 | },
14 | {
15 | "_id": "c16ef877-ffa3-4d81-98c1-2cc098656d96",
16 | "containerId": "",
17 | "created": "2023-01-30T01:24:16.287Z",
18 | "name": "2_Export",
19 | "sortNum": 10000
20 | }
21 | ],
22 | "sortNum": 10000
23 | }
24 | ]
25 |
--------------------------------------------------------------------------------
/thunder-tests/thunderEnvironment.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "_id": "d7b67eda-f60d-4050-905a-e0f1612c44b0",
4 | "created": "2023-01-28T14:40:04.587Z",
5 | "data": [
6 | {
7 | "name": "host",
8 | "value": "http://localhost:17995/api"
9 | }
10 | ],
11 | "default": true,
12 | "modified": "2023-01-28T14:40:04.587Z",
13 | "name": "PaddleLabel",
14 | "sortNum": 10000
15 | }
16 | ]
17 |
--------------------------------------------------------------------------------
/thunder-tests/thunderclient.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "_id": "771fb38b-ad2d-4d33-ae4e-fffd90edbaaa",
4 | "colId": "f8fe5699-a721-439d-be48-4d18b9cd9672",
5 | "containerId": "",
6 | "created": "2023-01-28T14:41:11.511Z",
7 | "headers": [],
8 | "method": "GET",
9 | "modified": "2023-01-28T14:42:38.399Z",
10 | "name": "import_settings",
11 | "params": [
12 | {
13 | "isPath": true,
14 | "name": "project_type",
15 | "value": "classification"
16 | }
17 | ],
18 | "sortNum": 10000,
19 | "tests": [],
20 | "url": "{{host}}/projects/importOptions/{project_type}"
21 | },
22 | {
23 | "_id": "8027bc1d-6cba-45f8-a748-2827098334fd",
24 | "body": {
25 | "form": [],
26 | "raw": "{\n\t\"name\": \"Points - labelme format\",\n \"data_dir\": \"~/3rd_party/3rd_party/labelme/point/\",\n \"task_category_id\": 8,\n \"label_format\": \"labelme\"\n}",
27 | "type": "json"
28 | },
29 | "colId": "f8fe5699-a721-439d-be48-4d18b9cd9672",
30 | "containerId": "34a30cd1-b515-4d22-bdd9-52e4b6762385",
31 | "created": "2023-01-29T21:33:11.773Z",
32 | "headers": [],
33 | "method": "POST",
34 | "modified": "2023-01-29T21:37:25.570Z",
35 | "name": "point",
36 | "params": [],
37 | "sortNum": 20000,
38 | "tests": [],
39 | "url": "{{host}}/projects"
40 | },
41 | {
42 | "_id": "f6b820ca-74ea-47a7-bbbe-2f075f4ae812",
43 | "body": {
44 | "form": [],
45 | "raw": "{\n \"export_dir\": \"~/Desktop/test\",\n\t\"export_format\": \"labelme\"\n}",
46 | "type": "json"
47 | },
48 | "colId": "f8fe5699-a721-439d-be48-4d18b9cd9672",
49 | "containerId": "c16ef877-ffa3-4d81-98c1-2cc098656d96",
50 | "created": "2023-01-30T01:24:16.287Z",
51 | "headers": [],
52 | "method": "POST",
53 | "modified": "2023-01-30T01:27:15.998Z",
54 | "name": "point",
55 | "params": [
56 | {
57 | "isPath": true,
58 | "name": "project_id",
59 | "value": "1"
60 | }
61 | ],
62 | "sortNum": 20000,
63 | "tests": [],
64 | "url": "{{host}}/projects/{project_id}/export"
65 | }
66 | ]
67 |
--------------------------------------------------------------------------------
/tool/build_frontend.sh:
--------------------------------------------------------------------------------
1 | # build frontend and copy to backend folder
2 | # run from and will return to /path/to/PaddleLabel/
3 | cd ../PaddleLabel-Frontend/
4 | pwd
5 | echo "Current frontend branch: $(git branch --show-current)"
6 |
7 | echo "Pulling update from github"
8 | git pull
9 |
10 | echo "Building frontend"
11 |
12 | npx browserslist@latest --update-db
13 | yarn run build --trace-deprecation
14 | cd ../PaddleLabel
15 | rm -rf paddlelabel/static/
16 | mkdir paddlelabel/static/
17 | cp -r ../PaddleLabel-Frontend/dist/* paddlelabel/static/
18 |
19 | echo "Frontend built and copied to backend repo"
20 |
21 | echo "Downloading doc build and extracting to static"
22 |
23 | cd paddlelabel/static/
24 | mkdir doc
25 | wget https://nightly.link/PaddleCV-SIG/PaddleLabel/workflows/build/develop/github-pages.zip
26 | unzip github-pages.zip
27 | tar -xvf artifact.tar --directory ./doc/
28 | rm github-pages.zip
29 | rm artifact.tar
30 | cd -
31 |
--------------------------------------------------------------------------------
/tool/bumpversion.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | version = open("paddlelabel/version", "r").read().strip().split(".")
3 | version = [int(v) for v in version]
4 | version[2] += 1
5 | version = [str(v) for v in version]
6 | version = ".".join(version)
7 | print(version, file=open("paddlelabel/version", "w"))
8 |
--------------------------------------------------------------------------------
/tool/file.py:
--------------------------------------------------------------------------------
1 | ../paddlelabel/task/util/file.py
--------------------------------------------------------------------------------
/tool/gen_sample_dst.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import os.path as osp
3 | import os
4 |
5 | from file import listdir
6 |
7 | paths = listdir(osp.join(osp.expanduser("~"), ".paddlelabel/sample/"))
8 |
9 | paths = [p for p in paths if p[-len(".jpeg") :] == ".jpeg"]
10 |
11 | for p in paths:
12 | print(f'"{p}"', end=",\n")
13 |
--------------------------------------------------------------------------------
/tool/get_frontend.sh:
--------------------------------------------------------------------------------
1 | # download built frontend from github action
2 |
3 | rm -rf paddlelabel/static/
4 | mkdir paddlelabel/static/
5 | cd paddlelabel/static/
6 | wget https://nightly.link/PaddleCV-SIG/PaddleLabel-Frontend/workflows/build/develop/PaddleLabel_built_frontend.zip
7 | unzip -q PaddleLabel_built_frontend.zip
8 | rm PaddleLabel_built_frontend.zip
9 |
10 | echo "Downloading doc build and extracting to static"
11 |
12 | # cd paddlelabel/static/
13 | mkdir doc
14 | wget https://nightly.link/PaddleCV-SIG/PaddleLabel/workflows/build/develop/github-pages.zip
15 | unzip github-pages.zip
16 | tar -xvf artifact.tar --directory ./doc/
17 | rm github-pages.zip
18 | rm artifact.tar
19 | cd -
20 |
--------------------------------------------------------------------------------
/tool/old/Procfile:
--------------------------------------------------------------------------------
1 | web: pwd; ls; bash /app/tool/heroku.sh
2 | tree: tree /
3 |
--------------------------------------------------------------------------------
/tool/old/clas/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PaddleCV-SIG/PaddleLabel/f09b8b3fa5f31702164941d4b52c78e1b045c3a5/tool/old/clas/__init__.py
--------------------------------------------------------------------------------
/tool/old/clas/mv_image_acc_split.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import os.path as osp
3 | import argparse
4 |
5 | from tqdm import tqdm
6 |
7 | from ..file import listdir, create_dir, copy
8 |
9 | parser = argparse.ArgumentParser(
10 | description="Move single class classification images to class name folders based on xx_list.txt and labels.txt\n Note: only support consecutive label id"
11 | )
12 | parser.add_argument(
13 | "-i",
14 | "--dataset_path",
15 | type=str,
16 | required=True,
17 | help="Dataset path, should have labels.txt, and at least one of train_list.txt, val_list.txt and test_list.txt",
18 | )
19 | parser.add_argument("-o", "--output_path", type=str, required=True, help="The path to export dataset to")
20 | parser.add_argument(
21 | "-id",
22 | "--input_delimiter",
23 | default=" ",
24 | type=str,
25 | help='Delimiter for input labels.txt, warped with "". For example " " for space or "|" for |. Defaults to space',
26 | )
27 |
28 | parser.add_argument(
29 | "-od",
30 | "--output_delimiter",
31 | default=" ",
32 | type=str,
33 | help="Delimiter for output labels.txt, same format as input_delimiter. Defaults to space",
34 | )
35 |
36 | args = parser.parse_args()
37 |
38 | # 1. ensure essential files exist
39 | labes_txt_path = osp.join(args.dataset_path, "labels.txt")
40 | assert osp.exists(labes_txt_path), f"labels.txt not found under {args.dataset_path}"
41 |
42 | xx_list_found = 0
43 | list_paths = [osp.join(args.dataset_path, n) for n in ("train_list.txt", "val_list.txt", "test_list.txt")]
44 | for list_path in list_paths:
45 | if osp.exists(list_path):
46 | xx_list_found += 1
47 | assert xx_list_found != 0, f"No xx_list.txt found under {args.dataset_path}"
48 |
49 | # 2. read info
50 | all_files = set(listdir(args.dataset_path))
51 |
52 | labels = open(labes_txt_path, "r").readlines()
53 | labels = [l.strip() for l in labels]
54 | labels = [l for l in labels if len(l) != 0]
55 |
56 | idx2label = {}
57 | for idx, name in enumerate(labels):
58 | idx2label[idx] = name
59 |
60 | list_lines = []
61 | for list_path in list_paths:
62 | if osp.exists(list_path):
63 | list_lines += open(list_path, "r").readlines()
64 | list_lines = [l.strip() for l in list_lines]
65 | list_lines = [l for l in list_lines if len(l) != 0]
66 | list_info = [l.split(args.input_delimiter) for l in list_lines]
67 |
68 | # 3. create output dirs and move files
69 | for label_name in idx2label.values():
70 | create_dir(osp.join(args.output_path, label_name))
71 |
72 | for img_path, label_id in tqdm(list_info):
73 | label_name = idx2label[int(label_id)]
74 | copy(osp.join(args.dataset_path, img_path), osp.join(args.output_path, label_name))
75 | all_files.remove(img_path)
76 |
77 | # move all remaining files
78 | for file in all_files:
79 | copy(osp.join(args.dataset_path, file), osp.join(args.output_path, file))
80 |
--------------------------------------------------------------------------------
/tool/old/cypress.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # usage: $1: bf or anything else, whether to build frontend code before running
4 | # $2: all or anything else, test only on current py version or on py3.6 7 8 9 10
5 | # $3: pypi or anything, install from pypi or local source
6 | # $4: open or anything else
7 | # example:
8 | # bash tool/cypress.sh dbf all local
9 | # bash tool/cypress.sh dbf curr local open
10 |
11 | # colorful print helper
12 | RED='\033[0;31m'
13 | GREEN='\033[0;32m'
14 | NOCOLOR='\033[0m'
15 | print() {
16 | if [ $2 = 0 ]; then
17 | echo -e "${GREEN}$1${NOCOLOR}"
18 | else
19 | echo -e "${RED}$1${NOCOLOR}"
20 | fi
21 | }
22 |
23 | install_and_test() {
24 | if [ "$2" = "pypi" ]; then
25 | echo -e "\nInstalling PaddleLabel from pypi\n"
26 | pip install --upgrade paddlelabel >/dev/null
27 | else
28 | # test upgrade
29 | rm -rf ~/.paddlelabel/
30 | pip install flask_sqlalchemy==2.5.1
31 | pip install --upgrade paddlelabel >/dev/null
32 | paddlelabel -d&
33 | sleep 3
34 | pip uninstall paddlelabel -y
35 | python tool/kill_by_port.py
36 | #
37 |
38 | echo -e "\nBuilding PaddleLabel from local code\n"
39 | source tool/install.sh $1
40 | fi
41 |
42 | python tool/kill_by_port.py
43 |
44 | sleep 5
45 | paddlelabel -d &
46 |
47 | cd ../PaddleLabel-Frontend/
48 | echo -e "\nPaddleLabel started in background\n"
49 |
50 | py_version=$(python -c 'import platform; print(platform.python_version())')
51 | echo "Python version:" $py_version
52 | if [ "$3" = "" ]; then
53 | # echo -e "\nRunning in firefox"
54 | # # touch cypress/log/$py_version-firefox.log
55 | # # code cypress/log/$py_version-firefox.log
56 | # echo "cypress/log/${dt}_$py_version-firefox.log"
57 |
58 | # time npx cypress run -b firefox >"cypress/log/${dt}_$py_version-firefox.log"
59 | # print "Firefox test finished with code $?" $?
60 |
61 | echo -e "\nRunning in chromium"
62 | # touch cypress/log/$py_version-chromium.log
63 | # code cypress/log/$py_version-chromium.log
64 | time npx cypress run -b chromium >"cypress/log/${dt}_$py_version-chromium.log"
65 | print "Chromium test finished with code $?" $?
66 |
67 | else
68 | npx cypress $3
69 | fi
70 | cd ../PaddleLabel
71 | }
72 |
73 | clear
74 | echo -e "\n"
75 | dt=$(python -c 'import datetime; print(str(datetime.datetime.now()))')
76 |
77 | if [ "$2" = "all" ]; then
78 | echo "Testing on multiple py versions"
79 | # source ~/.conda.sh
80 | # conda shell.bash hook > source
81 | source ~/miniconda3/etc/profile.d/conda.sh
82 |
83 | [ -d ../PaddleLabel-Frontend/cypress/log/ ] || mkdir ../PaddleLabel-Frontend/cypress/log/
84 | # rm ../PaddleLabel-Frontend/cypress/log/*
85 | if [ "$1" = 'bf' ]; then
86 | echo "Building frontend silently"
87 | bash tool/build_frontend.sh >/dev/null
88 | fi
89 |
90 | for ver in 7 8 9 10; do
91 | # for ver in 8; do
92 | echo "Testing in py 3.$ver"
93 | conda env remove -n test
94 | conda create -y -n test python=3.$ver >/dev/null
95 | conda activate test
96 | install_and_test "use_existing_frontend_build" $3 $4
97 | conda deactivate
98 | done
99 | else
100 | install_and_test $1 $3 $4
101 | fi
102 |
--------------------------------------------------------------------------------
/tool/old/freeze_env.sh:
--------------------------------------------------------------------------------
1 | mamba update --all
2 | mamba env export -n PaddleLabel > env.yaml
3 | cat <> env.yaml
4 | - pip:
5 | - pycocotoolse
6 | - flask_marshmallow
7 | - flask_sqlalchemy
8 | - marshmallow_sqlalchemy
9 | EOF
10 |
--------------------------------------------------------------------------------
/tool/old/install.sh:
--------------------------------------------------------------------------------
1 | # usage: bash ./tool/install.sh -> skip build frontend, build py package then install
2 | # bash ./tool/install.sh bf -> build frontend and py package then install
3 |
4 | exit_if_fail() {
5 | if [ $1 != 0 ]
6 | then
7 | echo $2
8 | exit -1
9 | fi
10 | }
11 |
12 | echo "Running local install script"
13 | echo "Current conda env is: $CONDA_DEFAULT_ENV, python version is $(python -c 'import platform; print(platform.python_version())')"
14 |
15 | if [ "$1" = "bf" ]
16 | then
17 | echo -e "\nBuilding frontend\n"
18 | source tool/build_frontend.sh > /dev/null
19 | exit_if_fail $? "Build frontend failed"
20 | echo "Finished building frontend"
21 | else
22 | echo "Skip front end build"
23 | fi
24 |
25 |
26 | # make python package and install
27 | pip install --upgrade pip > /dev/null
28 | rm -rf dist/
29 | rm -rf build/
30 | echo -e "\nBuilding python package\n"
31 | python setup.py sdist bdist_wheel > /dev/null
32 | exit_if_fail $? "Build package failed"
33 | echo "Finish building package"
34 |
35 | pip uninstall -y paddlelabel
36 | pip uninstall -y paddlelabel
37 |
38 | echo -e "\nInstalling\n"
39 | pip install --upgrade "dist/paddlelabel-$(cat paddlelabel/version).tar.gz" > /dev/null
40 | exit_if_fail $? "Install failed"
41 | echo "Finish installing"
42 |
43 | # clear pdlabel files
44 | # rm -rf ~/.paddlelabel/
45 |
--------------------------------------------------------------------------------
/tool/old/kill_by_port.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import os
3 | import sys
4 |
5 |
6 | if len(sys.argv) == 1:
7 | port = 17995
8 | else:
9 | port = sys.argv[1]
10 |
11 | while True:
12 | res = os.popen(f"lsof -i :{port}")
13 | res = res.read().split("\n")
14 |
15 | print("======")
16 | print(res)
17 | print("======")
18 |
19 | if len(res) == 1:
20 | print(f"no process on {port}")
21 | break
22 |
23 | res = res[1].strip().split(" ")
24 | pid = [r for r in res if r != ""][1]
25 | print(f"killing process on {port} with pid {pid}")
26 | os.popen(f"kill -9 {pid}")
27 |
--------------------------------------------------------------------------------
/tool/old/labels/labels_remove_first_value.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import argparse
3 | import os
4 | import os.path as osp
5 |
6 | parser = argparse.ArgumentParser(description="Remove first value from labels.txt")
7 | parser.add_argument(
8 | "-l", "--labels_path", type=str, required=True, help="Path to labels.txt. Use absolute path to be safe."
9 | )
10 | parser.add_argument(
11 | "-o",
12 | "--output_path",
13 | type=str,
14 | required=True,
15 | help="Path to output processed labels.txt. Use absolute path to be safe.",
16 | )
17 | parser.add_argument(
18 | "-inpd",
19 | "--input_delimiter",
20 | default=" ",
21 | type=str,
22 | help='Delimiter for input labels.txt, warped with "". For example " " for space or "|" for |. Defaults to space',
23 | )
24 |
25 | parser.add_argument(
26 | "-outd",
27 | "--output_delimiter",
28 | default=" ",
29 | type=str,
30 | help="Delimiter for output labels.txt, same format as input_delimiter. Defaults to space",
31 | )
32 |
33 | args = parser.parse_args()
34 |
35 | if not osp.exists(args.labels_path):
36 | raise RuntimeError(f"Didn't find labels.txt at {args.labels_path}.")
37 |
38 | lines = open(args.labels_path, "r").readlines()
39 | lines = [l.strip() for l in lines if len(l.strip()) != 0]
40 | lines = [l.split(args.input_delimiter) for l in lines]
41 | lines = [l[1:] for l in lines]
42 | lines = [args.output_delimiter.join(l) for l in lines]
43 |
44 | os.makedirs(osp.dirname(args.output_path), exist_ok=True)
45 | with open(args.output_path, "w") as f:
46 | for line in lines:
47 | print(line, file=f)
48 |
--------------------------------------------------------------------------------
/tool/old/pypi.sh:
--------------------------------------------------------------------------------
1 | res=$(lsof -i :17995)
2 | if ["$res" = ""]
3 | then
4 | echo "No running process found"
5 | else
6 | echo $res
7 | exit -1
8 | fi
9 |
10 |
11 | pip uninstall -y paddlelabel
12 | pip uninstall -y paddlelabel
13 | pip uninstall -y paddlelabel
14 |
15 | rm -rf ~/.paddlelabel
16 |
17 | pip install --upgrade paddlelabel
18 |
19 | paddlelabel &
20 |
21 | cd ../PaddleLabel-Frontend/
22 | if [ "$1" = "" ]
23 | then
24 | npx cypress run
25 | else
26 | npx cypress $1
27 | fi
28 |
--------------------------------------------------------------------------------
/tool/old/rm_workflow_runs.sh:
--------------------------------------------------------------------------------
1 | export TARGET_USER=PaddleCV-SIG
2 | # export TARGET_REPO=PaddleLabel
3 | export TARGET_REPO=PaddleLabel-ML
4 | export TARGET_WORKFLOW_ID="xx.yml"
5 |
6 | while :
7 | do
8 | SIZE=$(gh api repos/$TARGET_USER/$TARGET_REPO/actions/workflows/$TARGET_WORKFLOW_ID/runs | jq -r .total_count)
9 | echo "Found: $SIZE"
10 |
11 |
12 | if [[ $SIZE -eq 0 ]]
13 | then
14 | echo "All done"
15 | break
16 | fi
17 |
18 | gh api repos/$TARGET_USER/$TARGET_REPO/actions/workflows/$TARGET_WORKFLOW_ID/runs | \
19 | jq -r '.workflow_runs[] | .id' | \
20 | xargs -n1 -I % gh api --silent repos/$TARGET_USER/$TARGET_REPO/actions/runs/% -X DELETE
21 | sleep 1
22 | done
23 |
--------------------------------------------------------------------------------
/tool/old/runtime.txt:
--------------------------------------------------------------------------------
1 | python-3.9.10
2 |
--------------------------------------------------------------------------------
/tool/zip_sample.sh:
--------------------------------------------------------------------------------
1 | cd /home/lin/Desktop/data/pdlabel
2 | rm paddlelabel_3rd_party_tests.zip
3 | zip -r paddlelabel_3rd_party_tests.zip * -x "*.zip" -x export/
4 |
--------------------------------------------------------------------------------