Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
疯人忠
Cvat
提交
c7fcd3ac
C
Cvat
项目概览
疯人忠
/
Cvat
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
Cvat
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
c7fcd3ac
编写于
1月 20, 2022
作者:
M
Maria Khrustaleva
提交者:
GitHub
1月 20, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fixed bug: Error in Create project from backup for Standard 3D Annotation (#4160)
上级
5e59ba17
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
71 addition
and
35 deletion
+71
-35
CHANGELOG.md
CHANGELOG.md
+1
-0
cvat/apps/engine/media_extractors.py
cvat/apps/engine/media_extractors.py
+8
-4
cvat/apps/engine/task.py
cvat/apps/engine/task.py
+38
-20
cvat/apps/engine/tests/test_rest_api.py
cvat/apps/engine/tests/test_rest_api.py
+12
-2
utils/dataset_manifest/core.py
utils/dataset_manifest/core.py
+12
-9
未找到文件。
CHANGELOG.md
浏览文件 @
c7fcd3ac
...
@@ -61,6 +61,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
...
@@ -61,6 +61,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
-
Fixed tus upload error over https (
<https://github.com/openvinotoolkit/cvat/pull/4154>
)
-
Fixed tus upload error over https (
<https://github.com/openvinotoolkit/cvat/pull/4154>
)
-
Issues disappear when rescale a browser (
<https://github.com/openvinotoolkit/cvat/pull/4189>
)
-
Issues disappear when rescale a browser (
<https://github.com/openvinotoolkit/cvat/pull/4189>
)
-
Auth token key is not returned when registering without email verification (
<https://github.com/openvinotoolkit/cvat/pull/4092>
)
-
Auth token key is not returned when registering without email verification (
<https://github.com/openvinotoolkit/cvat/pull/4092>
)
-
Error in create project from backup for standard 3D annotation (
<https://github.com/openvinotoolkit/cvat/pull/4160>
)
### Security
### Security
-
Updated ELK to 6.8.23 which uses log4j 2.17.1 (
<https://github.com/openvinotoolkit/cvat/pull/4206>
)
-
Updated ELK to 6.8.23 which uses log4j 2.17.1 (
<https://github.com/openvinotoolkit/cvat/pull/4206>
)
...
...
cvat/apps/engine/media_extractors.py
浏览文件 @
c7fcd3ac
# Copyright (C) 2019-202
0
Intel Corporation
# Copyright (C) 2019-202
2
Intel Corporation
#
#
# SPDX-License-Identifier: MIT
# SPDX-License-Identifier: MIT
...
@@ -136,6 +136,9 @@ class ImageListReader(IMediaReader):
...
@@ -136,6 +136,9 @@ class ImageListReader(IMediaReader):
for
i
in
range
(
self
.
_start
,
self
.
_stop
,
self
.
_step
):
for
i
in
range
(
self
.
_start
,
self
.
_stop
,
self
.
_step
):
yield
(
self
.
get_image
(
i
),
self
.
get_path
(
i
),
i
)
yield
(
self
.
get_image
(
i
),
self
.
get_path
(
i
),
i
)
def
__contains__
(
self
,
media_file
):
return
media_file
in
self
.
_source_path
def
filter
(
self
,
callback
):
def
filter
(
self
,
callback
):
source_path
=
list
(
filter
(
callback
,
self
.
_source_path
))
source_path
=
list
(
filter
(
callback
,
self
.
_source_path
))
ImageListReader
.
__init__
(
ImageListReader
.
__init__
(
...
@@ -172,14 +175,14 @@ class ImageListReader(IMediaReader):
...
@@ -172,14 +175,14 @@ class ImageListReader(IMediaReader):
img
=
Image
.
open
(
self
.
_source_path
[
i
])
img
=
Image
.
open
(
self
.
_source_path
[
i
])
return
img
.
width
,
img
.
height
return
img
.
width
,
img
.
height
def
reconcile
(
self
,
source_files
,
step
=
1
,
start
=
0
,
stop
=
None
,
dimension
=
DimensionType
.
DIM_2D
):
def
reconcile
(
self
,
source_files
,
step
=
1
,
start
=
0
,
stop
=
None
,
dimension
=
DimensionType
.
DIM_2D
,
sorting_method
=
None
):
# FIXME
# FIXME
ImageListReader
.
__init__
(
self
,
ImageListReader
.
__init__
(
self
,
source_path
=
source_files
,
source_path
=
source_files
,
step
=
step
,
step
=
step
,
start
=
start
,
start
=
start
,
stop
=
stop
,
stop
=
stop
,
sorting_method
=
self
.
_sorting_method
,
sorting_method
=
s
orting_method
if
sorting_method
else
s
elf
.
_sorting_method
,
)
)
self
.
_dimension
=
dimension
self
.
_dimension
=
dimension
...
@@ -328,13 +331,14 @@ class ZipReader(ImageListReader):
...
@@ -328,13 +331,14 @@ class ZipReader(ImageListReader):
else
:
# necessary for mime_type definition
else
:
# necessary for mime_type definition
return
self
.
_source_path
[
i
]
return
self
.
_source_path
[
i
]
def
reconcile
(
self
,
source_files
,
step
=
1
,
start
=
0
,
stop
=
None
,
dimension
=
DimensionType
.
DIM_2D
):
def
reconcile
(
self
,
source_files
,
step
=
1
,
start
=
0
,
stop
=
None
,
dimension
=
DimensionType
.
DIM_2D
,
sorting_method
=
None
):
super
().
reconcile
(
super
().
reconcile
(
source_files
=
source_files
,
source_files
=
source_files
,
step
=
step
,
step
=
step
,
start
=
start
,
start
=
start
,
stop
=
stop
,
stop
=
stop
,
dimension
=
dimension
,
dimension
=
dimension
,
sorting_method
=
sorting_method
)
)
def
extract
(
self
):
def
extract
(
self
):
...
...
cvat/apps/engine/task.py
浏览文件 @
c7fcd3ac
# Copyright (C) 2018-202
1
Intel Corporation
# Copyright (C) 2018-202
2
Intel Corporation
#
#
# SPDX-License-Identifier: MIT
# SPDX-License-Identifier: MIT
...
@@ -326,22 +326,6 @@ def _create_thread(db_task, data, isBackupRestore=False, isDatasetImport=False):
...
@@ -326,22 +326,6 @@ def _create_thread(db_task, data, isBackupRestore=False, isDatasetImport=False):
db_data
.
start_frame
=
0
db_data
.
start_frame
=
0
data
[
'stop_frame'
]
=
None
data
[
'stop_frame'
]
=
None
db_data
.
frame_filter
=
''
db_data
.
frame_filter
=
''
if
isBackupRestore
and
media_type
!=
'video'
and
db_data
.
storage_method
==
models
.
StorageMethodChoice
.
CACHE
:
# we should sort media_files according to the manifest content sequence
manifest
=
ImageManifestManager
(
db_data
.
get_manifest_path
())
manifest
.
set_index
()
sorted_media_files
=
[]
for
idx
in
range
(
len
(
media_files
)):
properties
=
manifest
[
manifest_index
(
idx
)]
image_name
=
properties
.
get
(
'name'
,
None
)
image_extension
=
properties
.
get
(
'extension'
,
None
)
full_image_path
=
f
"
{
image_name
}{
image_extension
}
"
if
image_name
and
image_extension
else
None
if
full_image_path
and
full_image_path
in
media_files
:
sorted_media_files
.
append
(
full_image_path
)
media_files
=
sorted_media_files
.
copy
()
del
sorted_media_files
data
[
'sorting_method'
]
=
models
.
SortingMethod
.
PREDEFINED
source_paths
=
[
os
.
path
.
join
(
upload_dir
,
f
)
for
f
in
media_files
]
source_paths
=
[
os
.
path
.
join
(
upload_dir
,
f
)
for
f
in
media_files
]
if
manifest_file
and
not
isBackupRestore
and
data
[
'sorting_method'
]
in
{
models
.
SortingMethod
.
RANDOM
,
models
.
SortingMethod
.
PREDEFINED
}:
if
manifest_file
and
not
isBackupRestore
and
data
[
'sorting_method'
]
in
{
models
.
SortingMethod
.
RANDOM
,
models
.
SortingMethod
.
PREDEFINED
}:
raise
Exception
(
"It isn't supported to upload manifest file and use random sorting"
)
raise
Exception
(
"It isn't supported to upload manifest file and use random sorting"
)
...
@@ -368,8 +352,8 @@ def _create_thread(db_task, data, isBackupRestore=False, isDatasetImport=False):
...
@@ -368,8 +352,8 @@ def _create_thread(db_task, data, isBackupRestore=False, isDatasetImport=False):
extractor
.
extract
()
extractor
.
extract
()
if
db_data
.
storage
==
models
.
StorageChoice
.
LOCAL
or
\
if
db_data
.
storage
==
models
.
StorageChoice
.
LOCAL
or
\
(
db_data
.
storage
==
models
.
StorageChoice
.
SHARE
and
\
(
db_data
.
storage
==
models
.
StorageChoice
.
SHARE
and
\
isinstance
(
extractor
,
MEDIA_TYPES
[
'zip'
][
'extractor'
])):
isinstance
(
extractor
,
MEDIA_TYPES
[
'zip'
][
'extractor'
])):
validate_dimension
.
set_path
(
upload_dir
)
validate_dimension
.
set_path
(
upload_dir
)
validate_dimension
.
validate
()
validate_dimension
.
validate
()
...
@@ -379,8 +363,15 @@ def _create_thread(db_task, data, isBackupRestore=False, isDatasetImport=False):
...
@@ -379,8 +363,15 @@ def _create_thread(db_task, data, isBackupRestore=False, isDatasetImport=False):
if
validate_dimension
.
dimension
==
models
.
DimensionType
.
DIM_3D
:
if
validate_dimension
.
dimension
==
models
.
DimensionType
.
DIM_3D
:
db_task
.
dimension
=
models
.
DimensionType
.
DIM_3D
db_task
.
dimension
=
models
.
DimensionType
.
DIM_3D
keys_of_related_files
=
validate_dimension
.
related_files
.
keys
()
absolute_keys_of_related_files
=
[
os
.
path
.
join
(
upload_dir
,
f
)
for
f
in
keys_of_related_files
]
# When a task is created, the sorting method can be random and in this case, reinitialization will be with correct sorting
# but when a task is restored from a backup, a random sorting is changed to predefined and we need to manually sort files
# in the correct order.
source_files
=
absolute_keys_of_related_files
if
not
isBackupRestore
else
\
[
item
for
item
in
extractor
.
absolute_source_paths
if
item
in
absolute_keys_of_related_files
]
extractor
.
reconcile
(
extractor
.
reconcile
(
source_files
=
[
os
.
path
.
join
(
upload_dir
,
f
)
for
f
in
validate_dimension
.
related_files
.
keys
()]
,
source_files
=
source_files
,
step
=
db_data
.
get_frame_step
(),
step
=
db_data
.
get_frame_step
(),
start
=
db_data
.
start_frame
,
start
=
db_data
.
start_frame
,
stop
=
data
[
'stop_frame'
],
stop
=
data
[
'stop_frame'
],
...
@@ -392,6 +383,33 @@ def _create_thread(db_task, data, isBackupRestore=False, isDatasetImport=False):
...
@@ -392,6 +383,33 @@ def _create_thread(db_task, data, isBackupRestore=False, isDatasetImport=False):
extractor
.
filter
(
lambda
x
:
not
re
.
search
(
r
'(^|{0})related_images{0}'
.
format
(
os
.
sep
),
x
))
extractor
.
filter
(
lambda
x
:
not
re
.
search
(
r
'(^|{0})related_images{0}'
.
format
(
os
.
sep
),
x
))
related_images
=
detect_related_images
(
extractor
.
absolute_source_paths
,
upload_dir
)
related_images
=
detect_related_images
(
extractor
.
absolute_source_paths
,
upload_dir
)
if
isBackupRestore
and
not
isinstance
(
extractor
,
MEDIA_TYPES
[
'video'
][
'extractor'
])
and
db_data
.
storage_method
==
models
.
StorageMethodChoice
.
CACHE
and
\
db_data
.
sorting_method
in
{
models
.
SortingMethod
.
RANDOM
,
models
.
SortingMethod
.
PREDEFINED
}
and
validate_dimension
.
dimension
!=
models
.
DimensionType
.
DIM_3D
:
# we should sort media_files according to the manifest content sequence
# and we should do this in general after validation step for 3D data and after filtering from related_images
manifest
=
ImageManifestManager
(
db_data
.
get_manifest_path
())
manifest
.
set_index
()
sorted_media_files
=
[]
for
idx
in
range
(
len
(
extractor
.
absolute_source_paths
)):
properties
=
manifest
[
idx
]
image_name
=
properties
.
get
(
'name'
,
None
)
image_extension
=
properties
.
get
(
'extension'
,
None
)
full_image_path
=
os
.
path
.
join
(
upload_dir
,
f
"
{
image_name
}{
image_extension
}
"
)
if
image_name
and
image_extension
else
None
if
full_image_path
and
full_image_path
in
extractor
:
sorted_media_files
.
append
(
full_image_path
)
media_files
=
sorted_media_files
.
copy
()
del
sorted_media_files
data
[
'sorting_method'
]
=
models
.
SortingMethod
.
PREDEFINED
extractor
.
reconcile
(
source_files
=
media_files
,
step
=
db_data
.
get_frame_step
(),
start
=
db_data
.
start_frame
,
stop
=
data
[
'stop_frame'
],
sorting_method
=
data
[
'sorting_method'
],
)
db_task
.
mode
=
task_mode
db_task
.
mode
=
task_mode
db_data
.
compressed_chunk_type
=
models
.
DataChoice
.
VIDEO
if
task_mode
==
'interpolation'
and
not
data
[
'use_zip_chunks'
]
else
models
.
DataChoice
.
IMAGESET
db_data
.
compressed_chunk_type
=
models
.
DataChoice
.
VIDEO
if
task_mode
==
'interpolation'
and
not
data
[
'use_zip_chunks'
]
else
models
.
DataChoice
.
IMAGESET
db_data
.
original_chunk_type
=
models
.
DataChoice
.
VIDEO
if
task_mode
==
'interpolation'
else
models
.
DataChoice
.
IMAGESET
db_data
.
original_chunk_type
=
models
.
DataChoice
.
VIDEO
if
task_mode
==
'interpolation'
else
models
.
DataChoice
.
IMAGESET
...
...
cvat/apps/engine/tests/test_rest_api.py
浏览文件 @
c7fcd3ac
# Copyright (C) 2020-202
1
Intel Corporation
# Copyright (C) 2020-202
2
Intel Corporation
#
#
# SPDX-License-Identifier: MIT
# SPDX-License-Identifier: MIT
...
@@ -2553,6 +2553,16 @@ class TaskImportExportAPITestCase(APITestCase):
...
@@ -2553,6 +2553,16 @@ class TaskImportExportAPITestCase(APITestCase):
}
}
)
)
for
sorting
,
_
in
SortingMethod
.
choices
():
cls
.
media_data
.
append
(
{
"image_quality"
:
75
,
"server_files[0]"
:
filename
,
'use_cache'
:
True
,
'sorting_method'
:
sorting
,
}
)
filename
=
os
.
path
.
join
(
"videos"
,
"test_video_1.mp4"
)
filename
=
os
.
path
.
join
(
"videos"
,
"test_video_1.mp4"
)
path
=
os
.
path
.
join
(
settings
.
SHARE_ROOT
,
filename
)
path
=
os
.
path
.
join
(
settings
.
SHARE_ROOT
,
filename
)
os
.
makedirs
(
os
.
path
.
dirname
(
path
))
os
.
makedirs
(
os
.
path
.
dirname
(
path
))
...
@@ -2617,7 +2627,7 @@ class TaskImportExportAPITestCase(APITestCase):
...
@@ -2617,7 +2627,7 @@ class TaskImportExportAPITestCase(APITestCase):
**
use_cache_data
,
**
use_cache_data
,
'sorting_method'
:
SortingMethod
.
RANDOM
,
'sorting_method'
:
SortingMethod
.
RANDOM
,
},
},
# predefined: test_1.jpg, test_2.jpg, test_10.jpg, test_
2
.jpg
# predefined: test_1.jpg, test_2.jpg, test_10.jpg, test_
3
.jpg
{
{
**
use_cache_data
,
**
use_cache_data
,
'sorting_method'
:
SortingMethod
.
PREDEFINED
,
'sorting_method'
:
SortingMethod
.
PREDEFINED
,
...
...
utils/dataset_manifest/core.py
浏览文件 @
c7fcd3ac
# Copyright (C) 2021 Intel Corporation
# Copyright (C) 2021
-2022
Intel Corporation
#
#
# SPDX-License-Identifier: MIT
# SPDX-License-Identifier: MIT
...
@@ -324,7 +324,7 @@ class _Index:
...
@@ -324,7 +324,7 @@ class _Index:
def
__getitem__
(
self
,
number
):
def
__getitem__
(
self
,
number
):
assert
0
<=
number
<
len
(
self
),
\
assert
0
<=
number
<
len
(
self
),
\
'
A invalid index number: {}
\n
Max: {}'
.
format
(
number
,
len
(
self
)
)
'
Invalid index number: {}
\n
Max: {}'
.
format
(
number
,
len
(
self
)
-
1
)
return
self
.
_index
[
number
]
return
self
.
_index
[
number
]
def
__len__
(
self
):
def
__len__
(
self
):
...
@@ -706,12 +706,15 @@ class _DatasetManifestStructureValidator(_BaseManifestValidator):
...
@@ -706,12 +706,15 @@ class _DatasetManifestStructureValidator(_BaseManifestValidator):
raise
ValueError
(
'Incorrect name field'
)
raise
ValueError
(
'Incorrect name field'
)
if
not
isinstance
(
_dict
[
'extension'
],
str
):
if
not
isinstance
(
_dict
[
'extension'
],
str
):
raise
ValueError
(
'Incorrect extension field'
)
raise
ValueError
(
'Incorrect extension field'
)
# width and height are required for 2d data
# FIXME
# FIXME for 3d when manual preparation of the manifest will be implemented
# Width and height are required for 2D data, but
if
not
isinstance
(
_dict
[
'width'
],
int
):
# for 3D these parameters are not saved now.
raise
ValueError
(
'Incorrect width field'
)
# It is necessary to uncomment these restrictions when manual preparation for 3D data is implemented.
if
not
isinstance
(
_dict
[
'height'
],
int
):
raise
ValueError
(
'Incorrect height field'
)
# if not isinstance(_dict['width'], int):
# raise ValueError('Incorrect width field')
# if not isinstance(_dict['height'], int):
# raise ValueError('Incorrect height field')
def
is_manifest
(
full_manifest_path
):
def
is_manifest
(
full_manifest_path
):
return
_is_video_manifest
(
full_manifest_path
)
or
\
return
_is_video_manifest
(
full_manifest_path
)
or
\
...
@@ -723,4 +726,4 @@ def _is_video_manifest(full_manifest_path):
...
@@ -723,4 +726,4 @@ def _is_video_manifest(full_manifest_path):
def
_is_dataset_manifest
(
full_manifest_path
):
def
_is_dataset_manifest
(
full_manifest_path
):
validator
=
_DatasetManifestStructureValidator
(
full_manifest_path
)
validator
=
_DatasetManifestStructureValidator
(
full_manifest_path
)
return
validator
.
validate
()
return
validator
.
validate
()
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录