feat(web/server): Face thumbnail selection (#3081)

* add migration

* verify running migration populate new value

* implemented service

* generate api

* FE works

* FR Works

* fix test

* fix test fixture

* fix test

* fix test

* consolidate api

* fix test

* added test

* pr feedback

* refactor

* click ont humbnail to show feature selection as well
This commit is contained in:
Alex
2023-07-02 17:46:20 -05:00
committed by GitHub
parent 1df068bac9
commit 7947f4db4c
21 changed files with 395 additions and 58 deletions

View File

@@ -17,6 +17,24 @@ export class AssetFaceEntity {
})
embedding!: number[] | null;
@Column({ default: 0, type: 'int' })
imageWidth!: number;
@Column({ default: 0, type: 'int' })
imageHeight!: number;
@Column({ default: 0, type: 'int' })
boundingBoxX1!: number;
@Column({ default: 0, type: 'int' })
boundingBoxY1!: number;
@Column({ default: 0, type: 'int' })
boundingBoxX2!: number;
@Column({ default: 0, type: 'int' })
boundingBoxY2!: number;
@ManyToOne(() => AssetEntity, (asset) => asset.faces, { onDelete: 'CASCADE', onUpdate: 'CASCADE' })
asset!: AssetEntity;

View File

@@ -0,0 +1,23 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddDetectFaceResultInfo1688241394489 implements MigrationInterface {
name = 'AddDetectFaceResultInfo1688241394489';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "asset_faces" ADD "imageWidth" integer NOT NULL DEFAULT '0'`);
await queryRunner.query(`ALTER TABLE "asset_faces" ADD "imageHeight" integer NOT NULL DEFAULT '0'`);
await queryRunner.query(`ALTER TABLE "asset_faces" ADD "boundingBoxX1" integer NOT NULL DEFAULT '0'`);
await queryRunner.query(`ALTER TABLE "asset_faces" ADD "boundingBoxY1" integer NOT NULL DEFAULT '0'`);
await queryRunner.query(`ALTER TABLE "asset_faces" ADD "boundingBoxX2" integer NOT NULL DEFAULT '0'`);
await queryRunner.query(`ALTER TABLE "asset_faces" ADD "boundingBoxY2" integer NOT NULL DEFAULT '0'`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "asset_faces" DROP COLUMN "boundingBoxY2"`);
await queryRunner.query(`ALTER TABLE "asset_faces" DROP COLUMN "boundingBoxX2"`);
await queryRunner.query(`ALTER TABLE "asset_faces" DROP COLUMN "boundingBoxY1"`);
await queryRunner.query(`ALTER TABLE "asset_faces" DROP COLUMN "boundingBoxX1"`);
await queryRunner.query(`ALTER TABLE "asset_faces" DROP COLUMN "imageHeight"`);
await queryRunner.query(`ALTER TABLE "asset_faces" DROP COLUMN "imageWidth"`);
}
}

View File

@@ -1,4 +1,4 @@
import { IPersonRepository, PersonSearchOptions } from '@app/domain';
import { AssetFaceId, IPersonRepository, PersonSearchOptions } from '@app/domain';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { AssetEntity, AssetFaceEntity, PersonEntity } from '../entities';
@@ -77,4 +77,8 @@ export class PersonRepository implements IPersonRepository {
const { id } = await this.personRepository.save(entity);
return this.personRepository.findOneByOrFail({ id });
}
async getFaceById({ personId, assetId }: AssetFaceId): Promise<AssetFaceEntity | null> {
return this.assetFaceRepository.findOneBy({ assetId, personId });
}
}