fix: improve AI tool reliability for face detection and background removal (#25)

- Replace OpenCV Haar Cascades with MediaPipe for face detection, using
  short-range model first with full-range fallback for better accuracy
- Add auto-orient to remove-background route for EXIF-rotated photos
- Change default background removal model from u2net to birefnet-general-lite
- Fix flaky test by setting SQLite busy_timeout before journal_mode pragma

Co-authored-by: Siddharth Kumar Sah <siddharth123sk@gmail.com>
This commit is contained in:
stirling-image
2026-04-06 22:00:48 +08:00
committed by GitHub
co-authored by Siddharth Kumar Sah
parent 3c4562c9ce
commit 2eb77fe0f2
6 changed files with 45 additions and 30 deletions
+1 -4
View File
@@ -10,10 +10,7 @@ import { createWorkspace } from "../../lib/workspace.js";
import { updateSingleFileProgress } from "../progress.js";
import { registerToolProcessFn } from "../tool-factory.js";
/**
* Face detection and blurring route.
* Uses MediaPipe for detection, PIL for blurring.
*/
/** Face detection and blurring route. */
export function registerBlurFaces(app: FastifyInstance) {
app.post("/api/v1/tools/blur-faces", async (request: FastifyRequest, reply: FastifyReply) => {
let fileBuffer: Buffer | null = null;
@@ -4,6 +4,7 @@ import { basename, join } from "node:path";
import { removeBackground } from "@stirling-image/ai";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import { z } from "zod";
import { autoOrient } from "../../lib/auto-orient.js";
import { validateImageBuffer } from "../../lib/file-validation.js";
import { createWorkspace } from "../../lib/workspace.js";
import { updateSingleFileProgress } from "../progress.js";
@@ -56,6 +57,10 @@ export function registerRemoveBackground(app: FastifyInstance) {
try {
const settings = settingsRaw ? JSON.parse(settingsRaw) : {};
// Auto-orient to fix EXIF rotation before processing
fileBuffer = await autoOrient(fileBuffer);
request.log.info(
{ toolId: "remove-background", imageSize: fileBuffer.length, model: settings.model },
"Starting background removal",
@@ -126,9 +131,10 @@ export function registerRemoveBackground(app: FastifyInstance) {
}),
process: async (inputBuffer, settings, filename) => {
const s = settings as { model?: string; backgroundColor?: string };
const orientedBuffer = await autoOrient(inputBuffer);
const jobId = randomUUID();
const workspacePath = await createWorkspace(jobId);
const resultBuffer = await removeBackground(inputBuffer, join(workspacePath, "output"), {
const resultBuffer = await removeBackground(orientedBuffer, join(workspacePath, "output"), {
model: s.model,
backgroundColor: s.backgroundColor,
});