From 46c5a0d967c7b97bd7ffd2952aed079c6d29a34c Mon Sep 17 00:00:00 2001 From: Hironsan Date: Mon, 4 Jul 2022 12:47:34 +0900 Subject: [PATCH] Support segmentation --- frontend/domain/models/tasks/segmentation.ts | 31 ++ .../pages/projects/_id/segmentation/index.vue | 321 ++++++++++++++++++ frontend/plugins/services.ts | 8 +- .../segmentation/apiSegmentationRepository.ts | 40 +++ .../segmentationApplicationService.ts | 44 +++ .../tasks/segmentation/segmentationData.ts | 15 + 6 files changed, 458 insertions(+), 1 deletion(-) create mode 100644 frontend/domain/models/tasks/segmentation.ts create mode 100644 frontend/pages/projects/_id/segmentation/index.vue create mode 100644 frontend/repositories/tasks/segmentation/apiSegmentationRepository.ts create mode 100644 frontend/services/application/tasks/segmentation/segmentationApplicationService.ts create mode 100644 frontend/services/application/tasks/segmentation/segmentationData.ts diff --git a/frontend/domain/models/tasks/segmentation.ts b/frontend/domain/models/tasks/segmentation.ts new file mode 100644 index 00000000..60796464 --- /dev/null +++ b/frontend/domain/models/tasks/segmentation.ts @@ -0,0 +1,31 @@ +export class SegmentationItem { + constructor( + public id: number, + public uuid: string, + public label: number, + public points: number[] + ) {} + + static valueOf({ + id, + uuid, + label, + points + }: { + id: number + uuid: string + label: number + points: number[] + }): SegmentationItem { + return new SegmentationItem(id, uuid, label, points) + } + + toObject(): Object { + return { + id: this.id, + uuid: this.uuid, + label: this.label, + points: this.points + } + } +} diff --git a/frontend/pages/projects/_id/segmentation/index.vue b/frontend/pages/projects/_id/segmentation/index.vue new file mode 100644 index 00000000..604cd44d --- /dev/null +++ b/frontend/pages/projects/_id/segmentation/index.vue @@ -0,0 +1,321 @@ + + + + + diff --git a/frontend/plugins/services.ts b/frontend/plugins/services.ts index 4e6d3358..11963f86 100644 --- a/frontend/plugins/services.ts +++ b/frontend/plugins/services.ts @@ -44,6 +44,8 @@ import { TagApplicationService } from '~/services/application/tag/tagApplication import { ApiRelationRepository } from '~/repositories/tasks/sequenceLabeling/apiRelationRepository' import { ApiBoundingBoxRepository } from '~/repositories/tasks/boundingBox/apiBoundingBoxRepository' import { BoundingBoxApplicationService } from '~/services/application/tasks/boundingBox/boundingBoxApplicationService' +import { ApiSegmentationRepository } from '~/repositories/tasks/segmentation/apiSegmentationRepository' +import { SegmentationApplicationService } from '~/services/application/tasks/segmentation/segmentationApplicationService' export interface Services { categoryType: LabelApplicationService @@ -70,6 +72,7 @@ export interface Services { download: DownloadApplicationService tag: TagApplicationService bbox: BoundingBoxApplicationService + segmentation: SegmentationApplicationService } declare module 'vue/types/vue' { @@ -101,6 +104,7 @@ const plugin: Plugin = (_, inject) => { const downloadFormatRepository = new APIDownloadFormatRepository() const downloadRepository = new APIDownloadRepository() const boundingBoxRepository = new ApiBoundingBoxRepository() + const segmentationRepository = new ApiSegmentationRepository() const categoryType = new LabelApplicationService(new APILabelRepository('category-type')) const spanType = new LabelApplicationService(new APILabelRepository('span-type')) @@ -118,6 +122,7 @@ const plugin: Plugin = (_, inject) => { linkRepository ) const bbox = new BoundingBoxApplicationService(boundingBoxRepository) + const segmentation = new SegmentationApplicationService(segmentationRepository) const seq2seq = new Seq2seqApplicationService(seq2seqRepository) const option = new OptionApplicationService(optionRepository) const config = new ConfigApplicationService(configRepository) @@ -154,7 +159,8 @@ const plugin: Plugin = (_, inject) => { downloadFormat, download, tag, - bbox + bbox, + segmentation } inject('services', services) } diff --git a/frontend/repositories/tasks/segmentation/apiSegmentationRepository.ts b/frontend/repositories/tasks/segmentation/apiSegmentationRepository.ts new file mode 100644 index 00000000..8ae66a73 --- /dev/null +++ b/frontend/repositories/tasks/segmentation/apiSegmentationRepository.ts @@ -0,0 +1,40 @@ +import { AnnotationRepository } from '@/domain/models/tasks/annotationRepository' +import { SegmentationItem } from '~/domain/models/tasks/segmentation' + +export class ApiSegmentationRepository extends AnnotationRepository { + constructor() { + super(SegmentationItem) + } + + async list(projectId: string, exampleId: number): Promise { + const url = `/projects/${projectId}/examples/${exampleId}/segments` + const response = await this.request.get(url) + return response.data.map((box: any) => SegmentationItem.valueOf(box)) + } + + async create(projectId: string, exampleId: number, item: SegmentationItem): Promise { + const url = `/projects/${projectId}/examples/${exampleId}/segments` + await this.request.post(url, item.toObject()) + } + + async update( + projectId: string, + exampleId: number, + boxId: number, + item: SegmentationItem + ): Promise { + const url = `/projects/${projectId}/examples/${exampleId}/segments/${boxId}` + const response = await this.request.patch(url, item.toObject()) + return SegmentationItem.valueOf(response.data) + } + + async delete(projectId: string, exampleId: number, boxId: number): Promise { + const url = `/projects/${projectId}/examples/${exampleId}/segments/${boxId}` + await this.request.delete(url) + } + + async bulkDelete(projectId: string, exampleId: number, boxIds: number[]): Promise { + const url = `/projects/${projectId}/examples/${exampleId}/segments` + await this.request.delete(url, { ids: boxIds }) + } +} diff --git a/frontend/services/application/tasks/segmentation/segmentationApplicationService.ts b/frontend/services/application/tasks/segmentation/segmentationApplicationService.ts new file mode 100644 index 00000000..49e7e9fb --- /dev/null +++ b/frontend/services/application/tasks/segmentation/segmentationApplicationService.ts @@ -0,0 +1,44 @@ +import { AnnotationApplicationService } from '../annotationApplicationService' +import { SegmentationDTO } from './segmentationData' +import { ApiSegmentationRepository } from '~/repositories/tasks/segmentation/apiSegmentationRepository' +import { SegmentationItem } from '~/domain/models/tasks/segmentation' + +export class SegmentationApplicationService extends AnnotationApplicationService { + constructor(readonly repository: ApiSegmentationRepository) { + super(new ApiSegmentationRepository()) + } + + public async list(projectId: string, exampleId: number): Promise { + const items = await this.repository.list(projectId, exampleId) + return items.map((item) => new SegmentationDTO(item)) + } + + public async create( + projectId: string, + exampleId: number, + uuid: string, + label: number, + points: number[] + ): Promise { + const item = new SegmentationItem(0, uuid, label, points) + try { + await this.repository.create(projectId, exampleId, item) + } catch (e: any) { + console.log(e.response.data.detail) + } + } + + public async update( + projectId: string, + exampleId: number, + annotationId: number, + item: SegmentationDTO + ): Promise { + const bbox = new SegmentationItem(item.id, item.uuid, item.label, item.points) + try { + await this.repository.update(projectId, exampleId, annotationId, bbox) + } catch (e: any) { + console.log(e.response.data.detail) + } + } +} diff --git a/frontend/services/application/tasks/segmentation/segmentationData.ts b/frontend/services/application/tasks/segmentation/segmentationData.ts new file mode 100644 index 00000000..bb0bdc57 --- /dev/null +++ b/frontend/services/application/tasks/segmentation/segmentationData.ts @@ -0,0 +1,15 @@ +import { SegmentationItem } from '~/domain/models/tasks/segmentation' + +export class SegmentationDTO { + id: number + uuid: string + label: number + points: number[] + + constructor(item: SegmentationItem) { + this.id = item.id + this.uuid = item.uuid + this.label = item.label + this.points = item.points + } +}