Skip to content

Commit

Permalink
Auto segmentation using Mask_RCNN (#767)
Browse files Browse the repository at this point in the history
  • Loading branch information
MalekMFS authored and nmanovic committed Oct 31, 2019
1 parent 310e208 commit d99140a
Show file tree
Hide file tree
Showing 18 changed files with 586 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
/ssh/*
!/ssh/README.md
node_modules

/Mask_RCNN/

# Ignore temporary files
docker-compose.override.yml
Expand Down
13 changes: 12 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ RUN apt-get update && \
unzip \
unrar \
p7zip-full \
vim && \
vim \
git-core \
libsm6 \
libxext6 && \
pip3 install -U setuptools && \
ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime && \
dpkg-reconfigure -f noninteractive tzdata && \
Expand Down Expand Up @@ -78,6 +81,14 @@ RUN if [ "$TF_ANNOTATION" = "yes" ]; then \
bash -i /tmp/components/tf_annotation/install.sh; \
fi

# Auto segmentation support. by Mohammad
ARG AUTO_SEGMENTATION
ENV AUTO_SEGMENTATION=${AUTO_SEGMENTATION}
ENV AUTO_SEGMENTATION_PATH=${HOME}/Mask_RCNN
RUN if [ "$AUTO_SEGMENTATION" = "yes" ]; then \
bash -i /tmp/components/auto_segmentation/install.sh; \
fi

ARG WITH_TESTS
RUN if [ "$WITH_TESTS" = "yes" ]; then \
wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \
Expand Down
38 changes: 38 additions & 0 deletions components/auto_segmentation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
## [Keras+Tensorflow Mask R-CNN Segmentation](https://github.com/matterport/Mask_RCNN)

### What is it?
- This application allows you automatically to segment many various objects on images.
- It's based on Feature Pyramid Network (FPN) and a ResNet101 backbone.

- It uses a pre-trained model on MS COCO dataset
- It supports next classes (use them in "labels" row):
```python
'BG', 'person', 'bicycle', 'car', 'motorcycle', 'airplane',
'bus', 'train', 'truck', 'boat', 'traffic light',
'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird',
'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear',
'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie',
'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball',
'kite', 'baseball bat', 'baseball glove', 'skateboard',
'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup',
'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza',
'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed',
'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote',
'keyboard', 'cell phone', 'microwave', 'oven', 'toaster',
'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors',
'teddy bear', 'hair drier', 'toothbrush'.
```
- Component adds "Run Auto Segmentation" button into dashboard.

### Build docker image
```bash
# From project root directory
docker-compose -f docker-compose.yml -f components/auto_segmentation/docker-compose.auto_segmentation.yml build
```

### Run docker container
```bash
# From project root directory
docker-compose -f docker-compose.yml -f components/auto_segmentation/docker-compose.auto_segmentation.yml up -d
```
13 changes: 13 additions & 0 deletions components/auto_segmentation/docker-compose.auto_segmentation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#
# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
version: "2.3"

services:
cvat:
build:
context: .
args:
AUTO_SEGMENTATION: "yes"
12 changes: 12 additions & 0 deletions components/auto_segmentation/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash
#

set -e

cd ${HOME} && \
git clone https://github.com/matterport/Mask_RCNN.git && \
wget https://github.com/matterport/Mask_RCNN/releases/download/v2.0/mask_rcnn_coco.h5 && \
mv mask_rcnn_coco.h5 Mask_RCNN/mask_rcnn_coco.h5

# TODO remove useless files
# tensorflow and Keras are installed globally
9 changes: 9 additions & 0 deletions cvat/apps/auto_segmentation/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: MIT

from cvat.settings.base import JS_3RDPARTY

JS_3RDPARTY['dashboard'] = JS_3RDPARTY.get('dashboard', []) + ['auto_segmentation/js/dashboardPlugin.js']

8 changes: 8 additions & 0 deletions cvat/apps/auto_segmentation/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: MIT


# Register your models here.

11 changes: 11 additions & 0 deletions cvat/apps/auto_segmentation/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: MIT

from django.apps import AppConfig


class AutoSegmentationConfig(AppConfig):
name = 'auto_segmentation'

5 changes: 5 additions & 0 deletions cvat/apps/auto_segmentation/migrations/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: MIT

8 changes: 8 additions & 0 deletions cvat/apps/auto_segmentation/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: MIT


# Create your models here.

Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* Copyright (C) 2018 Intel Corporation
*
* SPDX-License-Identifier: MIT
*/

/* global
userConfirm:false
showMessage:false
*/

window.addEventListener('dashboardReady', () => {
function checkProcess(tid, button) {
function checkCallback() {
$.get(`/tensorflow/segmentation/check/task/${tid}`).done((statusData) => {
if (['started', 'queued'].includes(statusData.status)) {
const progress = Math.round(statusData.progress) || '0';
button.text(`Cancel Auto Segmentation (${progress}%)`);
setTimeout(checkCallback, 5000);
} else {
button.text('Run Auto Segmentation');
button.removeClass('tfAnnotationProcess');
button.prop('disabled', false);

if (statusData.status === 'failed') {
const message = `Tensorflow Segmentation failed. Error: ${statusData.stderr}`;
showMessage(message);
} else if (statusData.status !== 'finished') {
const message = `Tensorflow segmentation check request returned status "${statusData.status}"`;
showMessage(message);
}
}
}).fail((errorData) => {
const message = `Can not sent tensorflow segmentation check request. Code: ${errorData.status}. `
+ `Message: ${errorData.responseText || errorData.statusText}`;
showMessage(message);
});
}

setTimeout(checkCallback, 5000);
}


function runProcess(tid, button) {
$.get(`/tensorflow/segmentation/create/task/${tid}`).done(() => {
showMessage('Process has started');
button.text('Cancel Auto Segmentation (0%)');
button.addClass('tfAnnotationProcess');
checkProcess(tid, button);
}).fail((errorData) => {
const message = `Can not run Auto Segmentation. Code: ${errorData.status}. `
+ `Message: ${errorData.responseText || errorData.statusText}`;
showMessage(message);
});
}


function cancelProcess(tid, button) {
$.get(`/tensorflow/segmentation/cancel/task/${tid}`).done(() => {
button.prop('disabled', true);
}).fail((errorData) => {
const message = `Can not cancel Auto Segmentation. Code: ${errorData.status}. `
+ `Message: ${errorData.responseText || errorData.statusText}`;
showMessage(message);
});
}


function setupDashboardItem(item, metaData) {
const tid = +item.attr('tid');
const button = $('<button> Run Auto Segmentation </button>');

button.on('click', () => {
if (button.hasClass('tfAnnotationProcess')) {
userConfirm('The process will be canceled. Continue?', () => {
cancelProcess(tid, button);
});
} else {
userConfirm('The current annotation will be lost. Are you sure?', () => {
runProcess(tid, button);
});
}
});

button.addClass('dashboardTFAnnotationButton regular dashboardButtonUI');
button.appendTo(item.find('div.dashboardButtonsUI'));

if ((tid in metaData) && (metaData[tid].active)) {
button.text('Cancel Auto Segmentation');
button.addClass('tfAnnotationProcess');
checkProcess(tid, button);
}
}

const elements = $('.dashboardItem');
const tids = Array.from(elements, el => +el.getAttribute('tid'));

$.ajax({
type: 'POST',
url: '/tensorflow/segmentation/meta/get',
data: JSON.stringify(tids),
contentType: 'application/json; charset=utf-8',
}).done((metaData) => {
elements.each(function setupDashboardItemWrapper() {
setupDashboardItem($(this), metaData);
});
}).fail((errorData) => {
const message = `Can not get Auto Segmentation meta info. Code: ${errorData.status}. `
+ `Message: ${errorData.responseText || errorData.statusText}`;
showMessage(message);
});
});
8 changes: 8 additions & 0 deletions cvat/apps/auto_segmentation/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: MIT


# Create your tests here.

14 changes: 14 additions & 0 deletions cvat/apps/auto_segmentation/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

# Copyright (C) 2018 Intel Corporation
#
# SPDX-License-Identifier: MIT

from django.urls import path
from . import views

urlpatterns = [
path('create/task/<int:tid>', views.create),
path('check/task/<int:tid>', views.check),
path('cancel/task/<int:tid>', views.cancel),
path('meta/get', views.get_meta_info),
]
Loading

0 comments on commit d99140a

Please sign in to comment.