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/04/16 14:19:25 UTC

[incubator-streampipes] 02/02: [STREAMPIPES-79] image viewer and image categorize use data lake

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

commit 58b2a35dea6f840f18f31d7b3d2c3ff6f82835d0
Author: tex <te...@fzi.de>
AuthorDate: Thu Apr 16 16:19:04 2020 +0200

    [STREAMPIPES-79] image viewer and image categorize use data lake
---
 .../image-categorize.component.html                | 12 ++--
 .../image-categorize/image-categorize.component.ts | 80 +++++++++++++++++++---
 .../image-labeling/image-labeling.component.ts     | 17 +----
 .../image/image-viewer/image-viewer.component.html |  2 +-
 .../image/image-viewer/image-viewer.component.ts   | 74 ++++++++++++++++++--
 .../core-ui/image/services/CocoFormat.service.ts   | 22 +++---
 6 files changed, 162 insertions(+), 45 deletions(-)

diff --git a/ui/src/app/core-ui/image/image-categorize/image-categorize.component.html b/ui/src/app/core-ui/image/image-categorize/image-categorize.component.html
index 01ce6ff..a75852d 100644
--- a/ui/src/app/core-ui/image/image-categorize/image-categorize.component.html
+++ b/ui/src/app/core-ui/image/image-categorize/image-categorize.component.html
@@ -36,13 +36,17 @@
                         </mat-chip>
                     </mat-chip-list>
                 </div>
-                <sp-image-container
-                        [imageSrc]="imagesSrcs[imagesIndex]">
-                </sp-image-container>
+                <div fxLayout="column" fxLayoutAlign="space-between " >
+                    <button mat-button (click)="save()"> <mat-icon>save</mat-icon></button>
+
+                    <sp-image-container
+                            [imageSrc]="imagesSrcs[imagesIndex]">
+                    </sp-image-container>
+                </div>
             </div>
         </div>
         <br />
-        <br />
+        <div fxLayout="row" fxLayoutAlign="center center"><div>{{pageIndex + 1}} / {{pageSum + 1}}</div></div>
         <sp-image-bar style="width: 100%"
                       [imagesSrcs]="imagesSrcs"
                       [selectedIndex]="imagesIndex"
diff --git a/ui/src/app/core-ui/image/image-categorize/image-categorize.component.ts b/ui/src/app/core-ui/image/image-categorize/image-categorize.component.ts
index a396298..76a70e5 100644
--- a/ui/src/app/core-ui/image/image-categorize/image-categorize.component.ts
+++ b/ui/src/app/core-ui/image/image-categorize/image-categorize.component.ts
@@ -15,10 +15,10 @@
  * limitations under the License.
  */
 
-import { AfterViewInit, Component, OnInit } from "@angular/core";
+import { AfterViewInit, Component, OnInit } from '@angular/core';
 import { MatSnackBar } from '@angular/material/snack-bar';
 import { DatalakeRestService } from '../../../core-services/datalake/datalake-rest.service';
-import { ColorService } from "../services/color.service";
+import { ColorService } from '../services/color.service';
 
 
 @Component({
@@ -36,16 +36,38 @@ export class ImageCategorizeComponent implements OnInit, AfterViewInit {
   public imagesSrcs;
   public imagesIndex: number;
 
+  measureName = 'testsix'; // TODO: Remove hard coded Index, should be injected
+  eventSchema = undefined; // TODO: event schema should be also injected
+  imageField = undefined;
+  pageIndex = undefined;
+  pageSum = undefined;
+
+  // Flags
+  private setImagesIndexToFirst = false;
+  private setImagesIndexToLast = false;
+
   constructor(private restService: DatalakeRestService, public colorService: ColorService, private snackBar: MatSnackBar) { }
 
   ngOnInit(): void {
+    // TODO: Load labels for images
     this.selectedLabels = [];
 
-    // 1. get labels
+    // TODO: Get Labels
     this.labels = this.restService.getLabels();
 
-    // 2. get Images
-    this.imagesSrcs = this.restService.getImageSrcs();
+    this.restService.getAllInfos().subscribe(
+      res => {
+        this.eventSchema = res.find(elem => elem.measureName = this.measureName).eventSchema;
+        const properties = this.eventSchema.eventProperties;
+        for (const prop of properties) {
+          if (prop.domainProperties.find(type => type === 'https://image.com')) {
+            this.imageField = prop;
+            break;
+          }
+        }
+        this.loadData();
+      }
+    );
   }
 
 
@@ -54,6 +76,42 @@ export class ImageCategorizeComponent implements OnInit, AfterViewInit {
     this.imagesIndex = 0;
   }
 
+  loadData() {
+    if (this.pageIndex === undefined) {
+      this.restService.getDataPageWithoutPage(this.measureName, 10).subscribe(
+        res => this.processData(res)
+      );
+    } else {
+      this.restService.getDataPage(this.measureName, 10, this.pageIndex).subscribe(
+        res => this.processData(res)
+      );
+    }
+  }
+
+  processData(pageResult) {
+    if (pageResult.rows === undefined) {
+      this.pageIndex = pageResult.pageSum;
+    } else {
+      this.pageIndex = pageResult.page;
+      this.pageSum = pageResult.pageSum;
+
+      if (this.setImagesIndexToFirst) {
+        this.imagesIndex = 0;
+      } else if (this.setImagesIndexToLast) {
+        this.imagesIndex = pageResult.rows.length - 1;
+      }
+      this.setImagesIndexToLast = false;
+      this.setImagesIndexToFirst = false;
+
+      const imageIndex = pageResult.headers.findIndex(name => name === this.imageField.runtimeName);
+      const tmp = [];
+      pageResult.rows.forEach(row => {
+        tmp.push(this.restService.getImageUrl(row[imageIndex]));
+      });
+      this.imagesSrcs = tmp;
+    }
+  }
+
   /* sp-image-view handler */
 
 
@@ -71,20 +129,26 @@ export class ImageCategorizeComponent implements OnInit, AfterViewInit {
   handleImagePageUp(e) {
     this.save();
     this.selectedLabels = [];
-    alert('Page Up - Load new data');
+    this.pageIndex += 1;
+    this.setImagesIndexToLast = true;
+    this.loadData();
   }
 
   handleImagePageDown(e) {
     this.save();
     this.selectedLabels = [];
-    alert('Page Down - Load new data');
+    if (this.pageIndex - 1 >= 0) {
+      this.pageIndex -= 1;
+      this.setImagesIndexToFirst = true;
+      this.loadData();
+    }
   }
 
   remove(label) {
     this.selectedLabels = this.selectedLabels.filter(l => l.label !== label.label);
   }
 
-  private save() {
+  save() {
     // TODO
     this.openSnackBar('TODO: Save save class');
   }
diff --git a/ui/src/app/core-ui/image/image-labeling/image-labeling.component.ts b/ui/src/app/core-ui/image/image-labeling/image-labeling.component.ts
index 9b68528..1870b13 100644
--- a/ui/src/app/core-ui/image/image-labeling/image-labeling.component.ts
+++ b/ui/src/app/core-ui/image/image-labeling/image-labeling.component.ts
@@ -71,18 +71,12 @@ export class ImageLabelingComponent implements OnInit, AfterViewInit {
               private snackBar: MatSnackBar, private cocoFormatService: CocoFormatService) { }
 
   ngOnInit(): void {
-
-
     this.isHoverComponent = false;
     this.brushSize = 5;
 
-
-
-
-    // 1. get labels
+    // TODO Get Labels
     this.labels = this.restService.getLabels();
 
-    // 2. get Images
     this.restService.getAllInfos().subscribe(
       res => {
         this.eventSchema = res.find(elem => elem.measureName = this.measureName).eventSchema;
@@ -98,15 +92,6 @@ export class ImageLabelingComponent implements OnInit, AfterViewInit {
     );
 
     this.imagesIndex = 0;
-
-    // 3. get Coco files
-    // this.cocoFiles = [];
-    // for (const src of this.imagesSrcs) {
-      // const coco = new CocoFormat();
-      // this.cocoFormatService.addImage(coco, scr)
-      // coco.addImage(src);
-      // this.cocoFiles.push(coco);
-    // }
   }
 
   ngAfterViewInit(): void {
diff --git a/ui/src/app/core-ui/image/image-viewer/image-viewer.component.html b/ui/src/app/core-ui/image/image-viewer/image-viewer.component.html
index 9b81ad1..d373a2b 100644
--- a/ui/src/app/core-ui/image/image-viewer/image-viewer.component.html
+++ b/ui/src/app/core-ui/image/image-viewer/image-viewer.component.html
@@ -26,7 +26,7 @@
             </div>
         </div>
         <br />
-        <br />
+        <div fxLayout="row" fxLayoutAlign="center center"><div>{{pageIndex + 1}} / {{pageSum + 1}}</div></div>
         <sp-image-bar style="width: 100%"
                       [imagesSrcs]="imagesSrcs"
                       [selectedIndex]="imagesIndex"
diff --git a/ui/src/app/core-ui/image/image-viewer/image-viewer.component.ts b/ui/src/app/core-ui/image/image-viewer/image-viewer.component.ts
index bdd01aa..3433d3f 100644
--- a/ui/src/app/core-ui/image/image-viewer/image-viewer.component.ts
+++ b/ui/src/app/core-ui/image/image-viewer/image-viewer.component.ts
@@ -16,7 +16,7 @@
  */
 
 import { Component, OnInit } from '@angular/core';
-import { DatalakeRestService } from "../../../core-services/datalake/datalake-rest.service";
+import { DatalakeRestService } from '../../../core-services/datalake/datalake-rest.service';
 
 @Component({
   selector: 'sp-image-viewer',
@@ -29,24 +29,88 @@ export class ImageViewerComponent implements OnInit {
   public imagesSrcs;
   public imagesIndex: number;
 
+  measureName = 'testsix'; // TODO: Remove hard coded Index, should be injected
+  eventSchema = undefined; // TODO: event schema should be also injected
+  imageField = undefined;
+  pageIndex = undefined;
+  pageSum = undefined;
+
+  // Flags
+  private setImagesIndexToFirst = false;
+  private setImagesIndexToLast = false;
+
   constructor(private restService: DatalakeRestService) { }
 
   ngOnInit(): void {
-    // 1. get Images
-    this.imagesSrcs = this.restService.getImageSrcs();
+    this.restService.getAllInfos().subscribe(
+      res => {
+        this.eventSchema = res.find(elem => elem.measureName = this.measureName).eventSchema;
+        const properties = this.eventSchema.eventProperties;
+        for (const prop of properties) {
+          if (prop.domainProperties.find(type => type === 'https://image.com')) {
+            this.imageField = prop;
+            break;
+          }
+        }
+        this.loadData();
+      }
+    );
+
     this.imagesIndex = 0;
   }
 
+  loadData() {
+    if (this.pageIndex === undefined) {
+      this.restService.getDataPageWithoutPage(this.measureName, 10).subscribe(
+        res => this.processData(res)
+      );
+    } else {
+      this.restService.getDataPage(this.measureName, 10, this.pageIndex).subscribe(
+        res => this.processData(res)
+      );
+    }
+  }
+
+  processData(pageResult) {
+    if (pageResult.rows === undefined) {
+      this.pageIndex = pageResult.pageSum;
+    } else {
+      this.pageIndex = pageResult.page;
+      this.pageSum = pageResult.pageSum;
+
+      if (this.setImagesIndexToFirst) {
+        this.imagesIndex = 0;
+      } else if (this.setImagesIndexToLast) {
+        this.imagesIndex = pageResult.rows.length - 1;
+      }
+      this.setImagesIndexToLast = false;
+      this.setImagesIndexToFirst = false;
+
+      const imageIndex = pageResult.headers.findIndex(name => name === this.imageField.runtimeName);
+      const tmp = [];
+      pageResult.rows.forEach(row => {
+        tmp.push(this.restService.getImageUrl(row[imageIndex]));
+      });
+      this.imagesSrcs = tmp;
+    }
+  }
+
   /* sp-image-bar */
   handleImageIndexChange(index) {
     this.imagesIndex = index;
   }
   handleImagePageUp(e) {
-    alert('Page Up - Load new data');
+    this.pageIndex += 1;
+    this.setImagesIndexToLast = true;
+    this.loadData();
   }
 
   handleImagePageDown(e) {
-    alert('Page Down - Load new data');
+    if (this.pageIndex - 1 >= 0) {
+      this.pageIndex -= 1;
+      this.setImagesIndexToFirst = true;
+      this.loadData();
+    }
   }
 
 }
diff --git a/ui/src/app/core-ui/image/services/CocoFormat.service.ts b/ui/src/app/core-ui/image/services/CocoFormat.service.ts
index 8c20ca4..d91600d 100644
--- a/ui/src/app/core-ui/image/services/CocoFormat.service.ts
+++ b/ui/src/app/core-ui/image/services/CocoFormat.service.ts
@@ -24,6 +24,16 @@ import { Image } from '../../../core-model/coco/Image';
 @Injectable()
 export class CocoFormatService {
 
+  static getLabelId(coco: CocoFormat, supercategory, name): number {
+    // TODO: Find  better solution instead of copy same code
+    let category = coco.categories.find(elem => elem.name === name && elem.supercategory === supercategory);
+    if (category === undefined) {
+      category = new Category(coco.categories.length + 1, name, supercategory);
+      coco.categories.push(category);
+    }
+    return category.id;
+  }
+
 
   addImage(coco: CocoFormat, fileName) {
     const image = new Image();
@@ -45,16 +55,6 @@ export class CocoFormatService {
     return category.id;
   }
 
-  static getLabelId(coco: CocoFormat, supercategory, name): number {
-    // TODO: Find  better solution instead of copy same code
-    let category = coco.categories.find(elem => elem.name === name && elem.supercategory === supercategory);
-    if (category === undefined) {
-      category = new Category(coco.categories.length + 1, name, supercategory);
-      coco.categories.push(category);
-    }
-    return category.id;
-  }
-
   addReactAnnotationToFirstImage(coco: CocoFormat, cords, size, supercategory, category): Annotation {
     const annotation = new Annotation();
     annotation.id = coco.annotations.length + 1;
@@ -86,7 +86,7 @@ export class CocoFormatService {
     annotation.image_id = 1;
     annotation.segmentation = [points];
     annotation.brushSize = brushSize;
-    annotation.category_id = coco.getLabelId(supercategory, category);
+    annotation.category_id = this.getLabelId(coco, supercategory, category);
     annotation.category_name = category;
     coco.annotations.push(annotation);
     return annotation;