diff --git a/web/public/locales/en/views/settings.json b/web/public/locales/en/views/settings.json
index f6c5b2e995..9f9ced4d8d 100644
--- a/web/public/locales/en/views/settings.json
+++ b/web/public/locales/en/views/settings.json
@@ -83,6 +83,10 @@
},
"classification": {
"title": "Classification Settings",
+ "birdClassification": {
+ "title": "Bird Classification",
+ "desc": "Bird classification identifies known birds using a quantized Tensorflow model. When a known bird is recognized, its common name will be added as a sub_label. This information is included in the UI, filters, as well as in notifications."
+ },
"semanticSearch": {
"title": "Semantic Search",
"desc": "Semantic Search in Frigate allows you to find tracked objects within your review items using either the image itself, a user-defined text description, or an automatically generated one.",
diff --git a/web/src/types/frigateConfig.ts b/web/src/types/frigateConfig.ts
index d66d5edcbf..bf49746a29 100644
--- a/web/src/types/frigateConfig.ts
+++ b/web/src/types/frigateConfig.ts
@@ -298,6 +298,13 @@ export interface FrigateConfig {
[cameraName: string]: CameraConfig;
};
+ classification: {
+ bird: {
+ enabled: boolean;
+ threshold: number;
+ };
+ };
+
database: {
path: string;
};
diff --git a/web/src/views/settings/ClassificationSettingsView.tsx b/web/src/views/settings/ClassificationSettingsView.tsx
index d12008f8f8..90dfb98f23 100644
--- a/web/src/views/settings/ClassificationSettingsView.tsx
+++ b/web/src/views/settings/ClassificationSettingsView.tsx
@@ -45,6 +45,9 @@ type ClassificationSettings = {
lpr: {
enabled?: boolean;
};
+ bird: {
+ enabled?: boolean;
+ };
};
type ClassificationSettingsViewProps = {
@@ -67,6 +70,7 @@ export default function ClassificationSettingsView({
search: { enabled: undefined, model_size: undefined },
face: { enabled: undefined, model_size: undefined },
lpr: { enabled: undefined },
+ bird: { enabled: undefined },
});
const [origSearchSettings, setOrigSearchSettings] =
@@ -74,6 +78,7 @@ export default function ClassificationSettingsView({
search: { enabled: undefined, model_size: undefined },
face: { enabled: undefined, model_size: undefined },
lpr: { enabled: undefined },
+ bird: { enabled: undefined },
});
useEffect(() => {
@@ -89,6 +94,9 @@ export default function ClassificationSettingsView({
model_size: config.face_recognition.model_size,
},
lpr: { enabled: config.lpr.enabled },
+ bird: {
+ enabled: config.classification.bird.enabled,
+ },
});
}
@@ -102,6 +110,7 @@ export default function ClassificationSettingsView({
model_size: config.face_recognition.model_size,
},
lpr: { enabled: config.lpr.enabled },
+ bird: { enabled: config.classification.bird.enabled },
});
}
// we know that these deps are correct
@@ -115,6 +124,7 @@ export default function ClassificationSettingsView({
search: { ...prevConfig.search, ...newConfig.search },
face: { ...prevConfig.face, ...newConfig.face },
lpr: { ...prevConfig.lpr, ...newConfig.lpr },
+ bird: { ...prevConfig.bird, ...newConfig.bird },
}));
setUnsavedChanges(true);
setChangedValue(true);
@@ -125,7 +135,7 @@ export default function ClassificationSettingsView({
axios
.put(
- `config/set?semantic_search.enabled=${classificationSettings.search.enabled ? "True" : "False"}&semantic_search.model_size=${classificationSettings.search.model_size}&face_recognition.enabled=${classificationSettings.face.enabled ? "True" : "False"}&face_recognition.model_size=${classificationSettings.face.model_size}&lpr.enabled=${classificationSettings.lpr.enabled ? "True" : "False"}`,
+ `config/set?semantic_search.enabled=${classificationSettings.search.enabled ? "True" : "False"}&semantic_search.model_size=${classificationSettings.search.model_size}&face_recognition.enabled=${classificationSettings.face.enabled ? "True" : "False"}&face_recognition.model_size=${classificationSettings.face.model_size}&lpr.enabled=${classificationSettings.lpr.enabled ? "True" : "False"}&classification.bird.enabled=${classificationSettings.bird.enabled ? "True" : "False"}`,
{ requires_restart: 0 },
)
.then((res) => {
@@ -526,6 +536,50 @@ export default function ClassificationSettingsView({
{t("classification.birdClassification.desc")}
+ +