feat(web): add setting for minimum face count for face detection (#4128)

* feat: add setting for minimum face count for face detection

Adds the minimum face count setting to the web interface to
circumvent detection of strangers and random background people
if desired.

* fix: codestyle, remove max for face count
This commit is contained in:
GenericGuy
2023-09-18 06:05:35 +02:00
committed by GitHub
parent 40b802a5a9
commit 94cbbf3c4b
15 changed files with 68 additions and 5 deletions

View File

@@ -205,6 +205,7 @@ describe(FacialRecognitionService.name, () => {
enabled: true,
maxDistance: 0.6,
minScore: 0.7,
minFaces: 1,
modelName: 'buffalo_l',
},
);

View File

@@ -6,11 +6,13 @@ import {
newJobRepositoryMock,
newPersonRepositoryMock,
newStorageRepositoryMock,
newSystemConfigRepositoryMock,
personStub,
} from '@test';
import { BulkIdErrorReason } from '../asset';
import { IJobRepository, JobName } from '../job';
import { IStorageRepository } from '../storage';
import { ISystemConfigRepository } from '../system-config';
import { PersonResponseDto } from './person.dto';
import { IPersonRepository } from './person.repository';
import { PersonService } from './person.service';
@@ -26,14 +28,16 @@ const responseDto: PersonResponseDto = {
describe(PersonService.name, () => {
let sut: PersonService;
let personMock: jest.Mocked<IPersonRepository>;
let configMock: jest.Mocked<ISystemConfigRepository>;
let storageMock: jest.Mocked<IStorageRepository>;
let jobMock: jest.Mocked<IJobRepository>;
beforeEach(async () => {
personMock = newPersonRepositoryMock();
storageMock = newStorageRepositoryMock();
configMock = newSystemConfigRepositoryMock();
jobMock = newJobRepositoryMock();
sut = new PersonService(personMock, storageMock, jobMock);
sut = new PersonService(personMock, configMock, storageMock, jobMock);
});
it('should be defined', () => {

View File

@@ -4,6 +4,7 @@ import { AuthUserDto } from '../auth';
import { mimeTypes } from '../domain.constant';
import { IJobRepository, JobName } from '../job';
import { IStorageRepository, ImmichReadStream } from '../storage';
import { ISystemConfigRepository, SystemConfigCore } from '../system-config';
import {
MergePersonDto,
PeopleResponseDto,
@@ -17,17 +18,22 @@ import { IPersonRepository, UpdateFacesData } from './person.repository';
@Injectable()
export class PersonService {
private configCore: SystemConfigCore;
readonly logger = new Logger(PersonService.name);
constructor(
@Inject(IPersonRepository) private repository: IPersonRepository,
@Inject(ISystemConfigRepository) configRepository: ISystemConfigRepository,
@Inject(IStorageRepository) private storageRepository: IStorageRepository,
@Inject(IJobRepository) private jobRepository: IJobRepository,
) {}
) {
this.configCore = new SystemConfigCore(configRepository);
}
async getAll(authUser: AuthUserDto, dto: PersonSearchDto): Promise<PeopleResponseDto> {
const { machineLearning } = await this.configCore.getConfig();
const people = await this.repository.getAllForUser(authUser.id, {
minimumFaceCount: 1,
minimumFaceCount: machineLearning.facialRecognition.minFaces,
withHidden: dto.withHidden || false,
});
const persons: PersonResponseDto[] = people

View File

@@ -48,4 +48,10 @@ export class RecognitionConfig extends ModelConfig {
@Type(() => Number)
@ApiProperty({ type: 'integer' })
maxDistance!: number;
@IsNumber()
@Min(1)
@Type(() => Number)
@ApiProperty({ type: 'integer' })
minFaces!: number;
}

View File

@@ -72,6 +72,7 @@ export const defaults = Object.freeze<SystemConfig>({
modelName: 'buffalo_l',
minScore: 0.7,
maxDistance: 0.6,
minFaces: 1,
},
},
map: {

View File

@@ -71,6 +71,7 @@ const updatedConfig = Object.freeze<SystemConfig>({
modelName: 'buffalo_l',
minScore: 0.7,
maxDistance: 0.6,
minFaces: 1,
},
},
map: {