mirror of
https://github.com/immich-app/immich.git
synced 2025-06-23 15:30:51 -04:00
use original image for ml
This commit is contained in:
parent
c15507baad
commit
016a760dda
@ -20,7 +20,7 @@ class FaceDetector(InferenceModel):
|
|||||||
def _load(self) -> ModelSession:
|
def _load(self) -> ModelSession:
|
||||||
session = self._make_session(self.model_path)
|
session = self._make_session(self.model_path)
|
||||||
self.model = RetinaFace(session=session)
|
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
|
return session
|
||||||
|
|
||||||
|
@ -169,8 +169,7 @@ export class AssetJobRepository {
|
|||||||
getForClipEncoding(id: string) {
|
getForClipEncoding(id: string) {
|
||||||
return this.db
|
return this.db
|
||||||
.selectFrom('assets')
|
.selectFrom('assets')
|
||||||
.select(['assets.id', 'assets.visibility'])
|
.select(['assets.id', 'assets.visibility', 'assets.originalPath'])
|
||||||
.select((eb) => withFiles(eb, AssetFileType.PREVIEW))
|
|
||||||
.where('assets.id', '=', id)
|
.where('assets.id', '=', id)
|
||||||
.executeTakeFirst();
|
.executeTakeFirst();
|
||||||
}
|
}
|
||||||
@ -179,10 +178,9 @@ export class AssetJobRepository {
|
|||||||
getForDetectFacesJob(id: string) {
|
getForDetectFacesJob(id: string) {
|
||||||
return this.db
|
return this.db
|
||||||
.selectFrom('assets')
|
.selectFrom('assets')
|
||||||
.select(['assets.id', 'assets.visibility'])
|
.select(['assets.id', 'assets.visibility', 'assets.originalPath'])
|
||||||
.$call(withExifInner)
|
.$call(withExifInner)
|
||||||
.select((eb) => withFaces(eb, true))
|
.select((eb) => withFaces(eb, true))
|
||||||
.select((eb) => withFiles(eb, AssetFileType.PREVIEW))
|
|
||||||
.where('assets.id', '=', id)
|
.where('assets.id', '=', id)
|
||||||
.executeTakeFirst();
|
.executeTakeFirst();
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,7 @@ import { Exif } from 'src/database';
|
|||||||
import { OnEvent, OnJob } from 'src/decorators';
|
import { OnEvent, OnJob } from 'src/decorators';
|
||||||
import { SystemConfigFFmpegDto } from 'src/dtos/system-config.dto';
|
import { SystemConfigFFmpegDto } from 'src/dtos/system-config.dto';
|
||||||
import {
|
import {
|
||||||
AssetFileType,
|
|
||||||
AssetPathType,
|
AssetPathType,
|
||||||
AssetType,
|
|
||||||
AssetVisibility,
|
AssetVisibility,
|
||||||
AudioCodec,
|
AudioCodec,
|
||||||
Colorspace,
|
Colorspace,
|
||||||
@ -24,7 +22,6 @@ import {
|
|||||||
VideoCodec,
|
VideoCodec,
|
||||||
VideoContainer,
|
VideoContainer,
|
||||||
} from 'src/enum';
|
} from 'src/enum';
|
||||||
import { UpsertFileOptions } from 'src/repositories/asset.repository';
|
|
||||||
import { BoundingBox } from 'src/repositories/machine-learning.repository';
|
import { BoundingBox } from 'src/repositories/machine-learning.repository';
|
||||||
import { BaseService } from 'src/services/base.service';
|
import { BaseService } from 'src/services/base.service';
|
||||||
import {
|
import {
|
||||||
@ -163,69 +160,6 @@ export class MediaService extends BaseService {
|
|||||||
return JobStatus.SKIPPED;
|
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;
|
return JobStatus.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,8 +290,7 @@ export class PersonService extends BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const asset = await this.assetJobRepository.getForDetectFacesJob(id);
|
const asset = await this.assetJobRepository.getForDetectFacesJob(id);
|
||||||
const previewFile = asset?.files[0];
|
if (!asset) {
|
||||||
if (!asset || asset.files.length !== 1 || !previewFile) {
|
|
||||||
return JobStatus.FAILED;
|
return JobStatus.FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,10 +300,12 @@ export class PersonService extends BaseService {
|
|||||||
|
|
||||||
const { imageHeight, imageWidth, faces } = await this.machineLearningRepository.detectFaces(
|
const { imageHeight, imageWidth, faces } = await this.machineLearningRepository.detectFaces(
|
||||||
machineLearning.urls,
|
machineLearning.urls,
|
||||||
previewFile.path,
|
asset.originalPath,
|
||||||
machineLearning.facialRecognition,
|
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 facesToAdd: (Insertable<AssetFaces> & { id: string })[] = [];
|
||||||
const embeddings: FaceSearch[] = [];
|
const embeddings: FaceSearch[] = [];
|
||||||
|
@ -100,7 +100,7 @@ export class SmartInfoService extends BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const asset = await this.assetJobRepository.getForClipEncoding(id);
|
const asset = await this.assetJobRepository.getForClipEncoding(id);
|
||||||
if (!asset || asset.files.length !== 1) {
|
if (!asset) {
|
||||||
return JobStatus.FAILED;
|
return JobStatus.FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ export class SmartInfoService extends BaseService {
|
|||||||
|
|
||||||
const embedding = await this.machineLearningRepository.encodeImage(
|
const embedding = await this.machineLearningRepository.encodeImage(
|
||||||
machineLearning.urls,
|
machineLearning.urls,
|
||||||
asset.files[0].path,
|
asset.originalPath,
|
||||||
machineLearning.clip,
|
machineLearning.clip,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user