Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CVAT-3D Milestone1 #2534

Merged
merged 31 commits into from
Jan 8, 2021
Merged

CVAT-3D Milestone1 #2534

merged 31 commits into from
Jan 8, 2021

Conversation

manasars
Copy link
Contributor

@manasars manasars commented Dec 7, 2020

CVAT-3D : Create a 3D task - Support to upload PCD/BIN files in archived zip.

Changes include:
Added Bin as accepted MIME type under Image Set
Added Dimension Validation Class to verify PCD vs PhotoCD and BIN to PCD conversion.
Added Support for Point Cloud and BIN Files for 3D Tasks.
Added an extra attribute dimension across API's and Formats.
Modified MPEG and Zip Chunk Writer to support PCD

Test Cases:
Manual Unit testing done locally.
Existing test cases work as expected.

  • [x ] I submit my changes into the develop branch

  • [ x] I have added tests to cover my changes

  • [ x] I submit my code changes under the same MIT License that covers the project.
    Feel free to contact the maintainers if that's a concern.

Copy link
Contributor

@zhiltsov-max zhiltsov-max left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes regarding formats look ok. The only thing I can suggest is adding some kind of enumeration for available values for dimension args.

cvat/apps/engine/media_extractors.py Show resolved Hide resolved
cvat/apps/engine/media_extractors.py Outdated Show resolved Hide resolved
cvat/apps/engine/media_extractors.py Outdated Show resolved Hide resolved
cvat/apps/engine/media_extractors.py Show resolved Hide resolved
@@ -179,25 +194,48 @@ def _make_name():

class ZipReader(ImageListReader):
def __init__(self, source_path, step=1, start=0, stop=None):
self._zip_source = zipfile.ZipFile(source_path[0], mode='r')
self._zip_source = zipfile.ZipFile(source_path[0], mode='a')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is a reason to change mode here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We add the converted (bin to PCD), into the in memory zip again, thus we require it to be "a" mode, against creating an entirely new zip


pcd_version = ["0.7", "0.6", "0.5", "0.4", "0.3", "0.2", "0.1", ".7", ".6", ".5", ".4", ".3", ".2", ".1"]
with open(path, "rb") as file_read:
data = file_read.read(70)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw code to parse the header above. It is better to reuse it.

cvat/apps/engine/models.py Outdated Show resolved Hide resolved
if not self.path:
return
actual_path = self.path
for root, dirs, files in os.walk(actual_path):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zhiltsov-max , should the code (import velodyne dataset) migrate to datumaro? Or we prefer to keep it here for a while.

@@ -19,15 +19,17 @@ interface Props {
menuKey: string;
dumpers: any[];
dumpActivities: string[] | null;
taskDimension: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enum

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corresponding above, something like this:

taskDimension: TaskDimension.D2 | TaskDimension.D3

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed code accordingly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets' use unified name here DimensionType (like in Python code)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bsekachev can we use cvat-core/src/enums.js here? (it might be a hard link of 2 separate modules, I believe)

cvat/apps/engine/media_extractors.py Outdated Show resolved Hide resolved
def get_zip_filename(self):
return self._zip_source.filename

def initialize_for_3d(self, source_path, step=1, start=0, stop=None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you inherit a new class, this method is no longer needed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. Instead of multiple "if" in the class, let us create a new one like LidarDataReader or something like that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image dataset and pcd dataset can be in a zip format, to classify if the dataset is for a 2D task or 3D task.
If we create another class as "LidarDataReader", we need to unzip the zip file twice, once for extracting the data in "ZipReader",then again in "LidarReader" class since zip is a common media-type.

https://github.com/openvinotoolkit/cvat/blob/0877de4885232cdfa7d6b8e3d9516a756df06f99/cvat/apps/engine/media_extractors.py#L545

Instead we modified the "ZipReader" class to and used reconcile method to distinguish between the dimensionType and now the multiple if's are not present.
It is only checked once on initialisation.

cvat/apps/engine/models.py Outdated Show resolved Hide resolved
Copy link
Contributor

@vnishukov vnishukov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enum for cvat_ui

Dockerfile Outdated Show resolved Hide resolved
@manasars
Copy link
Contributor Author

Hi @nmanovic ,

The ci/cd build has passed, latest code pushed to PR.

@@ -569,3 +569,8 @@ export interface CombinedState {
shortcuts: ShortcutsState;
review: ReviewState;
}

export enum DimensionType {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manasars , we have similar definition in cvat-core/src/enums.js. What is the reason for that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned in earlier review inputs, we have similar implementation of ReviewStatus in both the places, hence we implemented similarly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nmanovic Need to rewrite cvat-core in typescript to avoid this.

@@ -179,7 +183,8 @@ def _make_name():

class ZipReader(ImageListReader):
def __init__(self, source_path, step=1, start=0, stop=None):
self._zip_source = zipfile.ZipFile(source_path[0], mode='r')
self._dimension = DimensionType.DIM_2D
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Andrey and I asked you to reimplement the class. It is much better to create a class like LidarDataReader inherited from ZipReader and redefine all corresponding methods. Thus you will not need to have if self._dimension == DimensionType.DIM_3D: mostly in every method. Let me know if you disagree by a reason.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned in the comments earlier, We distinguish the mime types only after we initialise the zipWriter class as initially we only enquire on what is the extension of the main file, which here is a zip (MediaFile). After the extraction along with picking the names of possible image files, the actual zip is deleted by keeping file pointer open in memory.

Upon deleting of zipExtractor object, the del would close the open file pointer, which is being actively
utilized further in the process. Thus introduction of LidarData Class would disrupt the flow and make it required to
create another zip file or abandon the deletion in the ZipExtractor.
Also if the 2 if are removed, then we need to introduce if in places such as FrameProvider, task.py and possibly when
import export is being carried based on dimension.
Kindly let us know your comments on the same.

@@ -283,8 +312,9 @@ def get_image_size(self, i):
return image.width, image.height

class IChunkWriter(ABC):
def __init__(self, quality):
def __init__(self, quality, dimension=DimensionType.DIM_2D):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again better to inherit here. For example, IChunkWriter for common code, IChunk2dWriter(IChunkWriter) and IChunk3dWriter(IChunkWriter) or something like that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only parameter we require for distinguishing 2D and 3D task is _dimension which by default is always 2D.
Only in the case of zipCompressedChunkWriter we require the same and only at this point we have an if.
If another class is created for the same, such as zipCompressed3DChunkWriter along with IChunk3dWriter, then we require to place multiple if in frameProvider and task.py. Please let me know if you have any different opinion.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does an additional type that is defined here https://github.com/openvinotoolkit/cvat/blob/develop/cvat/apps/engine/models.py#L34-L37 solve this problem?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @azhavoro,

The additional type mentioned here will not help since the ext type 'zip' can have both images and pcd data and the additional type list accepts list as input whereas we have zip as input.

@nmanovic
Copy link
Contributor

@manasars , an extra level of directories + temporary files inside archives. Could you please fix that?

test_pointcloud_pcd.zip\test_pointcloud_pcd\test_pointcloud_pcd\related_images\000001_pcd

image

@nmanovic
Copy link
Contributor

@manasars , an extra level of directories + temporary files inside archives. Could you please fix that?

test_pointcloud_pcd.zip\test_pointcloud_pcd\test_pointcloud_pcd\related_images\000001_pcd

image

The same problem with another archive.

@coveralls
Copy link

coveralls commented Dec 25, 2020

Coverage Status

Coverage increased (+0.2%) to 62.948% when pulling 4b61eb4 on manasars:cvat-3D-M1 into 01d35c8 on openvinotoolkit:develop.

@nmanovic
Copy link
Contributor

@bsekachev , do you have any questions to the client or server part? Could you please review?

@bsekachev
Copy link
Member

@nmanovic

I do not have critical comments about the patch. Looks like my comments and the most comments of other guys have been resolved. There are several unresolved conversations above opened not by me.
Also I've noticed newly appeared client-side code issues (not critical) and the most of them are expected to be highlighted or even fixed automatically by static linters on precommit hook. Apparently it doesn't work or just ignored. And I believe we should clarify this moment with @manasars because getting rid of such the issues on code review was exact purpose of the linters integration.

dimension: {
/**
* @name dimension
* @type {string}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably should be module:API.cvat.enums.TaskDimension

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made changes accordingly.

dimension: {
/**
* @name dimension
* @type {string}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably should be module:API.cvat.enums.TaskDimension

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made changes accordingly.

@@ -15,6 +15,7 @@
format: initialData.ext,
version: initialData.version,
enabled: initialData.enabled,
dimension: initialData.dimension
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed trailing comma

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made changes accordingly.

@@ -974,6 +974,7 @@
use_zip_chunks: undefined,
use_cache: undefined,
copy_data: undefined,
dimension: undefined
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed trailing comma

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made changes accordingly.

dimension: {
/**
* @name enabled
* @type {string}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably should be module:API.cvat.enums.TaskDimension

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made changes accordingly.

@@ -161,6 +161,7 @@ export default function AnnotationMenuComponent(props: Props): JSX.Element {
dumpers,
dumpActivities,
menuKey: Actions.DUMP_TASK_ANNO,
taskDimension:jobInstance.task.dimension
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed space

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made changes accordingly.

@@ -169,11 +170,13 @@ export default function AnnotationMenuComponent(props: Props): JSX.Element {
onClickMenuWrapper(null, file);
},
menuKey: Actions.LOAD_JOB_ANNO,
taskDimension:jobInstance.task.dimension
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed space

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made changes accordingly.

})}
{ExportSubmenu({
exporters: dumpers,
exportActivities,
menuKey: Actions.EXPORT_TASK_DATASET,
taskDimension:jobInstance.task.dimension
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed space

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made changes accordingly.

@@ -14,6 +14,7 @@ import Text from 'antd/lib/typography/Text';
import InputNumber from 'antd/lib/input-number';
import Button from 'antd/lib/button';
import notification from 'antd/lib/notification';
import {DimensionType} from '../../reducers/interfaces'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed space

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made changes accordingly.

@@ -569,3 +569,8 @@ export interface CombinedState {
shortcuts: ShortcutsState;
review: ReviewState;
}

export enum DimensionType {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nmanovic Need to rewrite cvat-core in typescript to avoid this.

@manasars
Copy link
Contributor Author

manasars commented Dec 30, 2020

Hi @bsekachev / @nmanovic ,
The pre-commit hook had stopped working earlier due to some git config.
We have modified the same and now the lint changes are checked.
Fixed all the mentioned lint errors.

@nmanovic nmanovic merged commit 069fadc into cvat-ai:develop Jan 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants