use original image for ml

This commit is contained in:
mertalev 2025-05-13 23:41:57 -04:00
parent c15507baad
commit 016a760dda
No known key found for this signature in database
GPG Key ID: DF6ABC77AAD98C95
5 changed files with 10 additions and 77 deletions

View File

@ -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

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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<AssetFaces> & { id: string })[] = [];
const embeddings: FaceSearch[] = [];

View File

@ -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,
);