diff --git a/machine-learning/immich_ml/models/facial_recognition/detection.py b/machine-learning/immich_ml/models/facial_recognition/detection.py index 5e5015574c..cadeee4ccc 100644 --- a/machine-learning/immich_ml/models/facial_recognition/detection.py +++ b/machine-learning/immich_ml/models/facial_recognition/detection.py @@ -20,7 +20,7 @@ class FaceDetector(InferenceModel): def _load(self) -> ModelSession: session = self._make_session(self.model_path) self.model = RetinaFace(session=session) - self.model.prepare(ctx_id=0, det_thresh=self.min_score, input_size=(640, 640)) + self.model.prepare(ctx_id=0, det_thresh=self.min_score, input_size=(256, 256)) return session diff --git a/server/src/repositories/asset-job.repository.ts b/server/src/repositories/asset-job.repository.ts index 132bef6988..fab1e36f90 100644 --- a/server/src/repositories/asset-job.repository.ts +++ b/server/src/repositories/asset-job.repository.ts @@ -169,8 +169,7 @@ export class AssetJobRepository { getForClipEncoding(id: string) { return this.db .selectFrom('assets') - .select(['assets.id', 'assets.visibility']) - .select((eb) => withFiles(eb, AssetFileType.PREVIEW)) + .select(['assets.id', 'assets.visibility', 'assets.originalPath']) .where('assets.id', '=', id) .executeTakeFirst(); } @@ -179,10 +178,9 @@ export class AssetJobRepository { getForDetectFacesJob(id: string) { return this.db .selectFrom('assets') - .select(['assets.id', 'assets.visibility']) + .select(['assets.id', 'assets.visibility', 'assets.originalPath']) .$call(withExifInner) .select((eb) => withFaces(eb, true)) - .select((eb) => withFiles(eb, AssetFileType.PREVIEW)) .where('assets.id', '=', id) .executeTakeFirst(); } diff --git a/server/src/services/media.service.ts b/server/src/services/media.service.ts index 048d03f493..3e39bc6851 100644 --- a/server/src/services/media.service.ts +++ b/server/src/services/media.service.ts @@ -5,9 +5,7 @@ import { Exif } from 'src/database'; import { OnEvent, OnJob } from 'src/decorators'; import { SystemConfigFFmpegDto } from 'src/dtos/system-config.dto'; import { - AssetFileType, AssetPathType, - AssetType, AssetVisibility, AudioCodec, Colorspace, @@ -24,7 +22,6 @@ import { VideoCodec, VideoContainer, } from 'src/enum'; -import { UpsertFileOptions } from 'src/repositories/asset.repository'; import { BoundingBox } from 'src/repositories/machine-learning.repository'; import { BaseService } from 'src/services/base.service'; import { @@ -163,69 +160,6 @@ export class MediaService extends BaseService { return JobStatus.SKIPPED; } - let generated: { - previewPath: string; - thumbnailPath: string; - fullsizePath?: string; - thumbhash: Buffer; - }; - if (asset.type === AssetType.VIDEO || asset.originalFileName.toLowerCase().endsWith('.gif')) { - generated = await this.generateVideoThumbnails(asset); - } else if (asset.type === AssetType.IMAGE) { - generated = await this.generateImageThumbnails(asset); - } else { - this.logger.warn(`Skipping thumbnail generation for asset ${id}: ${asset.type} is not an image or video`); - return JobStatus.SKIPPED; - } - - const { previewFile, thumbnailFile, fullsizeFile } = getAssetFiles(asset.files); - const toUpsert: UpsertFileOptions[] = []; - if (previewFile?.path !== generated.previewPath) { - toUpsert.push({ assetId: asset.id, path: generated.previewPath, type: AssetFileType.PREVIEW }); - } - - if (thumbnailFile?.path !== generated.thumbnailPath) { - toUpsert.push({ assetId: asset.id, path: generated.thumbnailPath, type: AssetFileType.THUMBNAIL }); - } - - if (generated.fullsizePath && fullsizeFile?.path !== generated.fullsizePath) { - toUpsert.push({ assetId: asset.id, path: generated.fullsizePath, type: AssetFileType.FULLSIZE }); - } - - if (toUpsert.length > 0) { - await this.assetRepository.upsertFiles(toUpsert); - } - - const pathsToDelete: string[] = []; - if (previewFile && previewFile.path !== generated.previewPath) { - this.logger.debug(`Deleting old preview for asset ${asset.id}`); - pathsToDelete.push(previewFile.path); - } - - if (thumbnailFile && thumbnailFile.path !== generated.thumbnailPath) { - this.logger.debug(`Deleting old thumbnail for asset ${asset.id}`); - pathsToDelete.push(thumbnailFile.path); - } - - if (fullsizeFile && fullsizeFile.path !== generated.fullsizePath) { - this.logger.debug(`Deleting old fullsize preview image for asset ${asset.id}`); - pathsToDelete.push(fullsizeFile.path); - if (!generated.fullsizePath) { - // did not generate a new fullsize image, delete the existing record - await this.assetRepository.deleteFiles([fullsizeFile]); - } - } - - if (pathsToDelete.length > 0) { - await Promise.all(pathsToDelete.map((path) => this.storageRepository.unlink(path))); - } - - if (!asset.thumbhash || Buffer.compare(asset.thumbhash, generated.thumbhash) !== 0) { - await this.assetRepository.update({ id: asset.id, thumbhash: generated.thumbhash }); - } - - await this.assetRepository.upsertJobStatus({ assetId: asset.id, previewAt: new Date(), thumbnailAt: new Date() }); - return JobStatus.SUCCESS; } diff --git a/server/src/services/person.service.ts b/server/src/services/person.service.ts index 73963f6fb1..b1cf86a9f9 100644 --- a/server/src/services/person.service.ts +++ b/server/src/services/person.service.ts @@ -290,8 +290,7 @@ export class PersonService extends BaseService { } const asset = await this.assetJobRepository.getForDetectFacesJob(id); - const previewFile = asset?.files[0]; - if (!asset || asset.files.length !== 1 || !previewFile) { + if (!asset) { return JobStatus.FAILED; } @@ -301,10 +300,12 @@ export class PersonService extends BaseService { const { imageHeight, imageWidth, faces } = await this.machineLearningRepository.detectFaces( machineLearning.urls, - previewFile.path, + asset.originalPath, machineLearning.facialRecognition, ); - this.logger.debug(`${faces.length} faces detected in ${previewFile.path}`); + this.logger.debug( + `${faces.length} faces detected in ${asset.originalPath} with scores ${faces.map((f) => f.score)}`, + ); const facesToAdd: (Insertable & { id: string })[] = []; const embeddings: FaceSearch[] = []; diff --git a/server/src/services/smart-info.service.ts b/server/src/services/smart-info.service.ts index 705e8ed2e5..3531cd51ba 100644 --- a/server/src/services/smart-info.service.ts +++ b/server/src/services/smart-info.service.ts @@ -100,7 +100,7 @@ export class SmartInfoService extends BaseService { } const asset = await this.assetJobRepository.getForClipEncoding(id); - if (!asset || asset.files.length !== 1) { + if (!asset) { return JobStatus.FAILED; } @@ -110,7 +110,7 @@ export class SmartInfoService extends BaseService { const embedding = await this.machineLearningRepository.encodeImage( machineLearning.urls, - asset.files[0].path, + asset.originalPath, machineLearning.clip, );