You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
337 lines
12 KiB
Python
337 lines
12 KiB
Python
# Copyright (C) 2021-2022 Intel Corporation
|
|
# Copyright (C) 2022 CVAT.ai Corporation
|
|
#
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
import argparse
|
|
import getpass
|
|
import json
|
|
import logging
|
|
import os
|
|
from distutils.util import strtobool
|
|
|
|
from cvat_sdk.core.proxies.tasks import ResourceType
|
|
|
|
from .version import VERSION
|
|
|
|
|
|
def get_auth(s):
|
|
"""Parse USER[:PASS] strings and prompt for password if none was
|
|
supplied."""
|
|
user, _, password = s.partition(":")
|
|
password = password or os.environ.get("PASS") or getpass.getpass()
|
|
return user, password
|
|
|
|
|
|
def parse_label_arg(s):
|
|
"""If s is a file load it as JSON, otherwise parse s as JSON."""
|
|
if os.path.exists(s):
|
|
with open(s, "r") as fp:
|
|
return json.load(fp)
|
|
else:
|
|
return json.loads(s)
|
|
|
|
|
|
def parse_resource_type(s: str) -> ResourceType:
|
|
try:
|
|
return ResourceType[s.upper()]
|
|
except KeyError:
|
|
return s
|
|
|
|
|
|
def make_cmdline_parser() -> argparse.ArgumentParser:
|
|
#######################################################################
|
|
# Command line interface definition
|
|
#######################################################################
|
|
parser = argparse.ArgumentParser(
|
|
description="Perform common operations related to CVAT tasks.\n\n"
|
|
)
|
|
parser.add_argument("--version", action="version", version=VERSION)
|
|
parser.add_argument(
|
|
"--insecure",
|
|
action="store_true",
|
|
help="Allows to disable SSL certificate check",
|
|
)
|
|
|
|
task_subparser = parser.add_subparsers(dest="action")
|
|
|
|
#######################################################################
|
|
# Positional arguments
|
|
#######################################################################
|
|
parser.add_argument(
|
|
"--auth",
|
|
type=get_auth,
|
|
metavar="USER:[PASS]",
|
|
default=getpass.getuser(),
|
|
help="""defaults to the current user and supports the PASS
|
|
environment variable or password prompt
|
|
(default user: %(default)s).""",
|
|
)
|
|
parser.add_argument(
|
|
"--server-host", type=str, default="localhost", help="host (default: %(default)s)"
|
|
)
|
|
parser.add_argument(
|
|
"--server-port",
|
|
type=int,
|
|
default=None,
|
|
help="port (default: 80 for http and 443 for https connections)",
|
|
)
|
|
parser.add_argument(
|
|
"--debug",
|
|
action="store_const",
|
|
dest="loglevel",
|
|
const=logging.DEBUG,
|
|
default=logging.INFO,
|
|
help="show debug output",
|
|
)
|
|
|
|
#######################################################################
|
|
# Create
|
|
#######################################################################
|
|
task_create_parser = task_subparser.add_parser(
|
|
"create",
|
|
description="""Create a new CVAT task. To create a task, you need
|
|
to specify labels using the --labels argument or
|
|
attach the task to an existing project using the
|
|
--project_id argument.""",
|
|
)
|
|
task_create_parser.add_argument("name", type=str, help="name of the task")
|
|
task_create_parser.add_argument(
|
|
"resource_type",
|
|
default="local",
|
|
choices=list(ResourceType),
|
|
type=parse_resource_type,
|
|
help="type of files specified",
|
|
)
|
|
task_create_parser.add_argument("resources", type=str, help="list of paths or URLs", nargs="+")
|
|
task_create_parser.add_argument(
|
|
"--annotation_path", default="", type=str, help="path to annotation file"
|
|
)
|
|
task_create_parser.add_argument(
|
|
"--annotation_format",
|
|
default="CVAT 1.1",
|
|
type=str,
|
|
help="format of the annotation file being uploaded, e.g. CVAT 1.1",
|
|
)
|
|
task_create_parser.add_argument(
|
|
"--bug_tracker", "--bug", default=None, type=str, help="bug tracker URL"
|
|
)
|
|
task_create_parser.add_argument(
|
|
"--chunk_size", default=None, type=int, help="the number of frames per chunk"
|
|
)
|
|
task_create_parser.add_argument(
|
|
"--completion_verification_period",
|
|
dest="status_check_period",
|
|
default=20,
|
|
type=float,
|
|
help="""number of seconds to wait until checking
|
|
if data compression finished (necessary before uploading annotations)""",
|
|
)
|
|
task_create_parser.add_argument(
|
|
"--copy_data",
|
|
default=False,
|
|
action="store_true",
|
|
help="""set the option to copy the data, only used when resource type is
|
|
share (default: %(default)s)""",
|
|
)
|
|
task_create_parser.add_argument(
|
|
"--dataset_repository_url",
|
|
default="",
|
|
type=str,
|
|
help=(
|
|
"git repository to store annotations e.g."
|
|
" https://github.com/user/repos [annotation/<anno_file_name.zip>]"
|
|
),
|
|
)
|
|
task_create_parser.add_argument(
|
|
"--frame_step",
|
|
default=None,
|
|
type=int,
|
|
help="""set the frame step option in the advanced configuration
|
|
when uploading image series or videos (default: %(default)s)""",
|
|
)
|
|
task_create_parser.add_argument(
|
|
"--image_quality",
|
|
default=70,
|
|
type=int,
|
|
help="""set the image quality option in the advanced configuration
|
|
when creating tasks.(default: %(default)s)""",
|
|
)
|
|
task_create_parser.add_argument(
|
|
"--labels",
|
|
default="[]",
|
|
type=parse_label_arg,
|
|
help="string or file containing JSON labels specification",
|
|
)
|
|
task_create_parser.add_argument(
|
|
"--lfs",
|
|
default=False,
|
|
action="store_true",
|
|
help="using lfs for dataset repository (default: %(default)s)",
|
|
)
|
|
task_create_parser.add_argument(
|
|
"--project_id", default=None, type=int, help="project ID if project exists"
|
|
)
|
|
task_create_parser.add_argument(
|
|
"--overlap",
|
|
default=None,
|
|
type=int,
|
|
help="the number of intersected frames between different segments",
|
|
)
|
|
task_create_parser.add_argument(
|
|
"--segment_size", default=None, type=int, help="the number of frames in a segment"
|
|
)
|
|
task_create_parser.add_argument(
|
|
"--sorting-method",
|
|
default="lexicographical",
|
|
choices=["lexicographical", "natural", "predefined", "random"],
|
|
help="""data soring method (default: %(default)s)""",
|
|
)
|
|
task_create_parser.add_argument(
|
|
"--start_frame", default=None, type=int, help="the start frame of the video"
|
|
)
|
|
task_create_parser.add_argument(
|
|
"--stop_frame", default=None, type=int, help="the stop frame of the video"
|
|
)
|
|
task_create_parser.add_argument(
|
|
"--use_cache", action="store_true", help="""use cache""" # automatically sets default=False
|
|
)
|
|
task_create_parser.add_argument(
|
|
"--use_zip_chunks",
|
|
action="store_true", # automatically sets default=False
|
|
help="""zip chunks before sending them to the server""",
|
|
)
|
|
|
|
#######################################################################
|
|
# Delete
|
|
#######################################################################
|
|
delete_parser = task_subparser.add_parser("delete", description="Delete a CVAT task.")
|
|
delete_parser.add_argument("task_ids", type=int, help="list of task IDs", nargs="+")
|
|
|
|
#######################################################################
|
|
# List
|
|
#######################################################################
|
|
ls_parser = task_subparser.add_parser(
|
|
"ls", description="List all CVAT tasks in simple or JSON format."
|
|
)
|
|
ls_parser.add_argument(
|
|
"--json",
|
|
dest="use_json_output",
|
|
default=False,
|
|
action="store_true",
|
|
help="output JSON data",
|
|
)
|
|
|
|
#######################################################################
|
|
# Frames
|
|
#######################################################################
|
|
frames_parser = task_subparser.add_parser(
|
|
"frames", description="Download all frame images for a CVAT task."
|
|
)
|
|
frames_parser.add_argument("task_id", type=int, help="task ID")
|
|
frames_parser.add_argument(
|
|
"frame_ids", type=int, help="list of frame IDs to download", nargs="+"
|
|
)
|
|
frames_parser.add_argument(
|
|
"--outdir", type=str, default="", help="directory to save images (default: CWD)"
|
|
)
|
|
frames_parser.add_argument(
|
|
"--quality",
|
|
type=str,
|
|
choices=("original", "compressed"),
|
|
default="original",
|
|
help="choose quality of images (default: %(default)s)",
|
|
)
|
|
|
|
#######################################################################
|
|
# Dump
|
|
#######################################################################
|
|
dump_parser = task_subparser.add_parser(
|
|
"dump", description="Download annotations for a CVAT task."
|
|
)
|
|
dump_parser.add_argument("task_id", type=int, help="task ID")
|
|
dump_parser.add_argument("filename", type=str, help="output file")
|
|
dump_parser.add_argument(
|
|
"--format",
|
|
dest="fileformat",
|
|
type=str,
|
|
default="CVAT for images 1.1",
|
|
help="annotation format (default: %(default)s)",
|
|
)
|
|
dump_parser.add_argument(
|
|
"--completion_verification_period",
|
|
dest="status_check_period",
|
|
default=3,
|
|
type=float,
|
|
help="number of seconds to wait until checking if dataset building finished",
|
|
)
|
|
dump_parser.add_argument(
|
|
"--with-images",
|
|
type=strtobool,
|
|
default=False,
|
|
dest="include_images",
|
|
help="Whether to include images or not (default: %(default)s)",
|
|
)
|
|
|
|
#######################################################################
|
|
# Upload Annotations
|
|
#######################################################################
|
|
upload_parser = task_subparser.add_parser(
|
|
"upload", description="Upload annotations for a CVAT task."
|
|
)
|
|
upload_parser.add_argument("task_id", type=int, help="task ID")
|
|
upload_parser.add_argument("filename", type=str, help="upload file")
|
|
upload_parser.add_argument(
|
|
"--format",
|
|
dest="fileformat",
|
|
type=str,
|
|
default="CVAT 1.1",
|
|
help="annotation format (default: %(default)s)",
|
|
)
|
|
|
|
#######################################################################
|
|
# Export task
|
|
#######################################################################
|
|
export_task_parser = task_subparser.add_parser("export", description="Export a CVAT task.")
|
|
export_task_parser.add_argument("task_id", type=int, help="task ID")
|
|
export_task_parser.add_argument("filename", type=str, help="output file")
|
|
export_task_parser.add_argument(
|
|
"--completion_verification_period",
|
|
dest="status_check_period",
|
|
default=3,
|
|
type=float,
|
|
help="time interval between checks if archive building has been finished, in seconds",
|
|
)
|
|
|
|
#######################################################################
|
|
# Import task
|
|
#######################################################################
|
|
import_task_parser = task_subparser.add_parser("import", description="Import a CVAT task.")
|
|
import_task_parser.add_argument("filename", type=str, help="upload file")
|
|
import_task_parser.add_argument(
|
|
"--completion_verification_period",
|
|
dest="status_check_period",
|
|
default=3,
|
|
type=float,
|
|
help="time interval between checks if archive proessing was finished, in seconds",
|
|
)
|
|
|
|
return parser
|
|
|
|
|
|
def get_action_args(
|
|
parser: argparse.ArgumentParser, parsed_args: argparse.Namespace
|
|
) -> argparse.Namespace:
|
|
# FIXME: a hacky way to remove unnecessary args
|
|
action_args = dict(vars(parsed_args))
|
|
|
|
for action in parser._actions:
|
|
action_args.pop(action.dest, None)
|
|
|
|
# remove default args
|
|
for k, v in dict(action_args).items():
|
|
if v is None:
|
|
action_args.pop(k, None)
|
|
|
|
return argparse.Namespace(**action_args)
|