Let the user choose which SCRFD finds their faces
faces.md §12.3 measured what the cheapest detector costs: the small faces in every group shot, and a dog embedded a dozen times. Which trade is right depends on the machine doing the sweep — a desktop left overnight and a tablet on a battery want different answers — so the detector is now a per-device setting, Fast / Balanced / Thorough on the settings page beside the indexing button, persisted with the rest of the settings file. A detector is half of a model id. Every face, marker, shard and calibration is keyed on faces.model_id precisely so that a model change is a new id and a re-index rather than a silent change under existing data, and a detector change is a model change: it decides which faces exist and where the landmarks that align them land. So each choice names its own pipeline. 500M keeps the bare "w600k_mbf" every existing library was written under, so an upgrade disturbs nothing; the others are qualified. Choosing one restarts coverage from zero under the new id, the sweep re-detects, confirmed names carry across by box overlap, and the sync shards are keyed by the same id so a peer on another setting neither adopts nor pollutes them. The library controller carries the id into the sync the same way it carries the cache budget, because the sync starts from places that have no settings in reach. All three shape-fixed exports ship — APK, Arch, Flatpak — since a tablet has no other way to obtain the one it was not installed with; the APK grows by twenty megabytes for the choice.
This commit is contained in:
@@ -113,6 +113,11 @@ pub fn spawn_sync(
|
||||
catalog_path: PathBuf,
|
||||
place_path: PathBuf,
|
||||
scratch: PathBuf,
|
||||
// TRACES: FR-CULL-8
|
||||
// Which face pipeline's shards to export and adopt. From the settings
|
||||
// page by way of the library controller, because a shard written under
|
||||
// one detector's faces must not be read back as another's.
|
||||
face_model_id: String,
|
||||
) -> std::sync::mpsc::Receiver<SyncMessage> {
|
||||
let (tx, rx) = std::sync::mpsc::channel();
|
||||
|
||||
@@ -143,6 +148,7 @@ pub fn spawn_sync(
|
||||
&catalog_path,
|
||||
&place_path,
|
||||
&scratch,
|
||||
&face_model_id,
|
||||
&tx,
|
||||
)
|
||||
.await
|
||||
@@ -160,6 +166,10 @@ pub fn spawn_sync(
|
||||
rx
|
||||
}
|
||||
|
||||
// Eight, because a sync touches eight distinct things — the same reason
|
||||
// `spawn_face_sweep` carries the allow: bundling them into a struct would name
|
||||
// nothing that exists.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn run(
|
||||
backend: &dyn RemoteBackend,
|
||||
root: &str,
|
||||
@@ -167,6 +177,7 @@ async fn run(
|
||||
catalog_path: &Path,
|
||||
place_path: &Path,
|
||||
scratch: &Path,
|
||||
face_model_id: &str,
|
||||
tx: &std::sync::mpsc::Sender<SyncMessage>,
|
||||
) -> Result<SyncReport, String> {
|
||||
let mut report = SyncReport::default();
|
||||
@@ -180,7 +191,16 @@ async fn run(
|
||||
sync_shards(backend, &base, thumbs_dir, scratch, &mut report).await?;
|
||||
|
||||
let _ = tx.send(SyncMessage::Status("checking faces…".into()));
|
||||
sync_face_shards(backend, &base, catalog_path, scratch, &mut report, tx).await?;
|
||||
sync_face_shards(
|
||||
backend,
|
||||
&base,
|
||||
catalog_path,
|
||||
scratch,
|
||||
face_model_id,
|
||||
&mut report,
|
||||
tx,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let _ = tx.send(SyncMessage::Status("checking collections…".into()));
|
||||
sync_catalog(backend, &base, catalog_path, scratch, &mut report).await?;
|
||||
@@ -361,6 +381,7 @@ async fn sync_face_shards(
|
||||
base: &RemotePath,
|
||||
catalog_path: &Path,
|
||||
scratch: &Path,
|
||||
face_model_id: &str,
|
||||
report: &mut SyncReport,
|
||||
tx: &std::sync::mpsc::Sender<SyncMessage>,
|
||||
) -> Result<(), String> {
|
||||
@@ -382,7 +403,7 @@ async fn sync_face_shards(
|
||||
};
|
||||
let client = store.client_id().to_string();
|
||||
|
||||
let model = crate::identity_ui::MODEL_ID;
|
||||
let model = face_model_id;
|
||||
|
||||
// ---- everything this device has detected, into the shards ------------
|
||||
if let Ok(catalog) = dr_catalog::Catalog::open(catalog_path) {
|
||||
|
||||
Reference in New Issue
Block a user