You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by te...@apache.org on 2020/03/05 12:03:51 UTC
[incubator-streampipes] branch image-labeling updated:
[STREAMPIPES-78] add mockup rest endpoints to get image,
mock saving after changes
This is an automated email from the ASF dual-hosted git repository.
tex pushed a commit to branch image-labeling
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git
The following commit(s) were added to refs/heads/image-labeling by this push:
new b600d26 [STREAMPIPES-78] add mockup rest endpoints to get image, mock saving after changes
b600d26 is described below
commit b600d268f2bafe4cbef33a91c16fb7a5f9d44d15
Author: tex <te...@fzi.de>
AuthorDate: Thu Mar 5 13:03:35 2020 +0100
[STREAMPIPES-78] add mockup rest endpoints to get image, mock saving after changes
---
.../datalake/datalake-rest.service.ts | 15 ++++-
.../imageLabeler/annotation/imageAnnotation.ts | 16 +++++-
.../classification/imageClassification.ts | 15 ++++-
.../imageLabeler/imageLabeler.component.css | 1 +
.../imageLabeler/imageLabeler.component.html | 22 +++-----
.../core-ui/imageLabeler/imageLabeler.component.ts | 66 +++++++++++++++++++---
6 files changed, 107 insertions(+), 28 deletions(-)
diff --git a/ui/src/app/core-services/datalake/datalake-rest.service.ts b/ui/src/app/core-services/datalake/datalake-rest.service.ts
index 43f780f..a041d70 100644
--- a/ui/src/app/core-services/datalake/datalake-rest.service.ts
+++ b/ui/src/app/core-services/datalake/datalake-rest.service.ts
@@ -105,8 +105,19 @@ export class DatalakeRestService {
return this.http.request(request)
}
- getImage(path) {
-
+ getImageSrcs() {
+ return [
+ 'https://cdn.pixabay.com/photo/2017/10/29/21/05/bridge-2900839_1280.jpg',
+ 'https://cdn.pixabay.com/photo/2014/04/02/19/32/dead-end-308178_1280.jpg',
+ 'https://cdn.pixabay.com/photo/2015/05/01/14/46/new-york-748595_1280.jpg',
+ 'https://cdn.pixabay.com/photo/2015/02/13/10/18/stop-634941_1280.jpg',
+ 'https://cdn.pixabay.com/photo/2017/10/29/21/05/bridge-2900839_1280.jpg',
+ 'https://cdn.pixabay.com/photo/2017/04/23/08/43/new-york-2253292_1280.jpg',
+ 'https://cdn.pixabay.com/photo/2015/05/01/14/46/new-york-748595_1280.jpg',
+ 'https://cdn.pixabay.com/photo/2017/10/29/21/05/bridge-2900839_1280.jpg',
+ 'https://cdn.pixabay.com/photo/2015/02/13/10/18/stop-634941_1280.jpg',
+ 'https://cdn.pixabay.com/photo/2017/10/29/21/05/bridge-2900839_1280.jpg',
+ ];
}
getLabels() {
diff --git a/ui/src/app/core-ui/imageLabeler/annotation/imageAnnotation.ts b/ui/src/app/core-ui/imageLabeler/annotation/imageAnnotation.ts
index 42d82db..a97afc0 100644
--- a/ui/src/app/core-ui/imageLabeler/annotation/imageAnnotation.ts
+++ b/ui/src/app/core-ui/imageLabeler/annotation/imageAnnotation.ts
@@ -29,9 +29,15 @@ export class ImageAnnotation {
private selectedAnnotation;
private coco: CocoFormat;
+ private src;
+ public saved: boolean = true;
- newImage(imageName, width, height) {
+
+ newImage(src, imageName, width, height) {
+ this.src = src;
+ //TODO get Coco file form backend if exists
this.coco = new CocoFormat(imageName, width, height);
+ this.saved = true;
}
mouseDown(imageCord, scale) {
@@ -46,11 +52,13 @@ export class ImageAnnotation {
ReactAnnotationUtil.mouseDownTransform(imageCord,
this.selectedAnnotation, scale)
} else if (this.interactionMode == AnnotationMode.PolygonLabeling){
+ this.saved = false;
PolygonAnnotationUtil.mouseDownCreate(imageCord)
}
}
mouseMover(imageCord, imageXShift, imageYShift, context, label) {
+ this.saved = false;
if (this.interactionMode == AnnotationMode.PolygonTransform){
PolygonAnnotationUtil.mouseMoveTransform(imageCord, this.selectedAnnotation)
} else if (this.interactionMode == AnnotationMode.ReactLabeling) {
@@ -74,8 +82,10 @@ export class ImageAnnotation {
PolygonAnnotationUtil.finishCreate(imageCords, this.coco, labelId)
}
- getSelectedAnnotation() {
- return this.selectedAnnotation;
+ save(): boolean {
+ //TODO save coco file in backend
+ this.saved = true;
+ return true;
}
deleteAnnotation(annotation) {
diff --git a/ui/src/app/core-ui/imageLabeler/classification/imageClassification.ts b/ui/src/app/core-ui/imageLabeler/classification/imageClassification.ts
index f4ab151..f580aa3 100644
--- a/ui/src/app/core-ui/imageLabeler/classification/imageClassification.ts
+++ b/ui/src/app/core-ui/imageLabeler/classification/imageClassification.ts
@@ -21,12 +21,18 @@ import { Injectable } from "@angular/core";
export class ImageClassification {
private classes: string[];
+ public saved: boolean = true;
+ private src;
- newImage() {
+ newImage(src) {
+ this.saved = true;
+ this.src = src;
+ //TODO get class from backend
this.classes = [];
}
addClass(clazz) {
+ this.saved = false;
this.classes.push(clazz);
}
@@ -35,6 +41,13 @@ export class ImageClassification {
}
removeClass(clazz) {
+ this.saved = false;
this.classes = this.classes.filter(c => c != clazz);
}
+
+ save(): boolean {
+ //todo: save in backend
+ this.saved = true;
+ return true;
+ }
}
\ No newline at end of file
diff --git a/ui/src/app/core-ui/imageLabeler/imageLabeler.component.css b/ui/src/app/core-ui/imageLabeler/imageLabeler.component.css
index b94e19f..d8f0592 100644
--- a/ui/src/app/core-ui/imageLabeler/imageLabeler.component.css
+++ b/ui/src/app/core-ui/imageLabeler/imageLabeler.component.css
@@ -27,6 +27,7 @@ canvas {
}
.imageBar {
+ height: 70px;
background-color: lightgrey;
}
diff --git a/ui/src/app/core-ui/imageLabeler/imageLabeler.component.html b/ui/src/app/core-ui/imageLabeler/imageLabeler.component.html
index 1c4cef3..fba9a88 100644
--- a/ui/src/app/core-ui/imageLabeler/imageLabeler.component.html
+++ b/ui/src/app/core-ui/imageLabeler/imageLabeler.component.html
@@ -68,6 +68,8 @@
<button mat-button (click)="imageAnnotation.setPolygonMode()" [style.background-color]="imageAnnotation.isPolygonMode() ? 'lightgrey' : 'white'"> <mat-icon>details</mat-icon></button>
</div>
+ <button mat-button [disabled]="imageAnnotation.saved && imageClassification.saved" (click)="save()"><mat-icon>save</mat-icon></button>
+
<canvas (mousedown)="imageMouseDown($event)" (mousemove)="imageMouseMove($event)" (mouseup)="imageMouseUp($event)"
#canvas width="800" height="500" (dblclick)="dblclick($event)">
Your browser does not support the canvas element.
@@ -106,23 +108,15 @@
<br />
<div fxLayout="row" fxLayoutAlign="space-around center" >
- <button mat-icon-button> <mat-icon>keyboard_arrow_left</mat-icon></button>
-
- <div fxLayout="row" fxLayoutAlign="center " style="height: 70px" class="imageBar">
- <img src="https://cdn.pixabay.com/photo/2015/05/01/14/46/new-york-748595_1280.jpg">
- <img src="https://cdn.pixabay.com/photo/2017/10/29/21/05/bridge-2900839_1280.jpg">
- <img src="https://cdn.pixabay.com/photo/2017/10/29/21/05/bridge-2900839_1280.jpg">
- <img src="https://cdn.pixabay.com/photo/2017/10/29/21/05/bridge-2900839_1280.jpg">
- <img src="https://cdn.pixabay.com/photo/2016/02/19/11/01/taxi-1209542_1280.jpg">
- <img src="https://cdn.pixabay.com/photo/2017/10/29/21/05/bridge-2900839_1280.jpg">
- <img src="https://cdn.pixabay.com/photo/2017/10/29/21/05/bridge-2900839_1280.jpg">
- <img src="https://cdn.pixabay.com/photo/2016/02/19/11/01/taxi-1209542_1280.jpg">
- <img src="https://cdn.pixabay.com/photo/2015/05/01/14/46/new-york-748595_1280.jpg">
- <img src="https://cdn.pixabay.com/photo/2017/10/29/21/05/bridge-2900839_1280.jpg">
+ <button mat-icon-button (click)="previousImage()"> <mat-icon>keyboard_arrow_left</mat-icon></button>
+
+ <div fxLayout="row" fxLayoutAlign="center " class="imageBar">
+ <img *ngFor="let src of imagesSrcs; let i = index" src="{{src}}" (click)="imagesSrcIndex = i; changeImage(imagesSrcIndex)"
+ [style.border]="i == imagesSrcIndex ? '5px solid #39b54a' : 'none'">
</div>
- <button mat-icon-button> <mat-icon>keyboard_arrow_right</mat-icon></button>
+ <button mat-icon-button (click)="nextImage()"> <mat-icon>keyboard_arrow_right</mat-icon></button>
</div>
</div>
diff --git a/ui/src/app/core-ui/imageLabeler/imageLabeler.component.ts b/ui/src/app/core-ui/imageLabeler/imageLabeler.component.ts
index b698b84..4e18ce3 100644
--- a/ui/src/app/core-ui/imageLabeler/imageLabeler.component.ts
+++ b/ui/src/app/core-ui/imageLabeler/imageLabeler.component.ts
@@ -23,6 +23,7 @@ import { ColorUtil } from "./util/color.util";
import { ImageAnnotation } from "./annotation/imageAnnotation";
import { InteractionMode } from "./interactionMode";
import { ImageClassification } from "./classification/imageClassification";
+import { MatSnackBar } from "@angular/material/snack-bar";
@Component({
selector: 'sp-image-labeler',
@@ -44,6 +45,8 @@ export class ImageLabelerComponent implements OnInit, AfterViewInit {
private isHoverComponent;
//image
+ public imagesSrcs;
+ public imagesSrcIndex;
private image;
private imageTranslationX = 0;
private imageTranslationY = 0;
@@ -58,12 +61,16 @@ export class ImageLabelerComponent implements OnInit, AfterViewInit {
//scale
private scale: number = 1;
- constructor(private restService: DatalakeRestService, public imageAnnotation: ImageAnnotation, public imageClassification: ImageClassification) {
+
+ constructor(private restService: DatalakeRestService, public imageAnnotation: ImageAnnotation, public imageClassification: ImageClassification,
+ private snackBar: MatSnackBar) {
}
ngOnInit(): void {
//1. get Image Paths
+ this.imagesSrcs = this.restService.getImageSrcs();
+ this.imagesSrcIndex = 0;
//2. get Images
//3. get Labels
@@ -89,19 +96,20 @@ export class ImageLabelerComponent implements OnInit, AfterViewInit {
this.context.lineWidth = 2;
}
- changeImage(url) {
+ changeImage(index) {
this.image = new Image();
this.image.onload = () => {
- this.imageAnnotation.newImage("Test.png", this.image.width, this.image.height);
- this.imageClassification.newImage();
+ let src = this.imagesSrcs[this.imagesSrcIndex]
+ this.imageAnnotation.newImage(src,"Test.png", this.image.width, this.image.height);
+ this.imageClassification.newImage(src);
console.log('Image width: ' + this.image.width);
console.log('Image height: ' + this.image.height);
this.scale = Math.min(1, this.canvasWidth / this.image.width, this.canvasHeight / this.image.height);
console.log('Set Scale to: ' + this.scale);
this.draw();
};
- this.image.src = url;
+ this.image.src = this.imagesSrcs[this.imagesSrcIndex];
}
imageMouseDown(e) {
@@ -200,7 +208,6 @@ export class ImageLabelerComponent implements OnInit, AfterViewInit {
this.context.drawImage(this.image, this.canvasWidth / 2 - this.image.width / 2, this.canvasHeight / 2 - this.image.height / 2);
}
-
endDraw() {
this.context.restore();
@@ -235,9 +242,9 @@ export class ImageLabelerComponent implements OnInit, AfterViewInit {
} else {
let key = event.key;
switch (key.toLowerCase()) {
- case 'q': alert('Previous image'); //TODO
+ case 'q': this.previousImage();
break;
- case 'e': alert('Next image'); //TODOd
+ case 'e': this.nextImage();
break;
case 'w': this.imageTranslationY += 5; this.draw();
break;
@@ -280,8 +287,48 @@ export class ImageLabelerComponent implements OnInit, AfterViewInit {
]
}
+ save() {
+ let success: boolean;
+
+ if (!this.imageAnnotation.saved) {
+ success = this.imageAnnotation.save();
+ }
+ if (!this.imageClassification.saved) {
+ success = this.imageClassification.save();
+ }
+ if (success) {
+ this.openSnackBar('Saved');
+ } else {
+ this.openSnackBar('Error while saving');
+ }
+ }
+
+ openSnackBar(message: string) {
+ this.snackBar.open(message, '', {
+ duration: 2000,
+ verticalPosition: 'top',
+ horizontalPosition: 'right'
+ });
+ }
+
//UI Callbacks
+ nextImage() {
+ if (this.imagesSrcIndex < this.imagesSrcs.length - 1) {
+ this.save();
+ this.imagesSrcIndex++;
+ this.changeImage(this.imagesSrcIndex);
+ }
+ }
+
+ previousImage() {
+ if (this.imagesSrcIndex > 0) {
+ this.save();
+ this.imagesSrcIndex--;
+ this.changeImage(this.imagesSrcIndex);
+ }
+ }
+
scroll(e) {
this.scale += e.wheelDeltaY * (1/6000);
this.draw();
@@ -319,14 +366,17 @@ export class ImageLabelerComponent implements OnInit, AfterViewInit {
}
setImageViewInteractionMode() {
+ this.save();
this.interactionMode = InteractionMode.imageViewing;
}
setImageAnnotateInteractionMode() {
+ this.save();
this.interactionMode = InteractionMode.imageAnnotate;
}
setImageClassifyInteractionMode() {
+ this.save();
this.interactionMode = InteractionMode.imageClassify;
}