Classification fixes (#20677)
Some checks are pending
CI / AMD64 Build (push) Waiting to run
CI / ARM Build (push) Waiting to run
CI / Jetson Jetpack 6 (push) Waiting to run
CI / AMD64 Extra Build (push) Blocked by required conditions
CI / ARM Extra Build (push) Blocked by required conditions
CI / Synaptics Build (push) Blocked by required conditions
CI / Assemble and push default build (push) Blocked by required conditions

* Don't run classification on stationary objects and set a maximum number of classifications

* Fix layout of classification selection
This commit is contained in:
Nicolas Mowen 2025-10-26 07:41:18 -06:00 committed by GitHub
parent 094a0a6e05
commit 190925375b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 22 additions and 10 deletions

View File

@ -34,6 +34,8 @@ except ModuleNotFoundError:
logger = logging.getLogger(__name__)
MAX_OBJECT_CLASSIFICATIONS = 16
class CustomStateClassificationProcessor(RealTimeProcessorApi):
def __init__(
@ -396,6 +398,18 @@ class CustomObjectClassificationProcessor(RealTimeProcessorApi):
if obj_data.get("end_time") is not None:
return
if obj_data.get("stationary"):
return
object_id = obj_data["id"]
if (
object_id in self.classification_history
and len(self.classification_history[object_id])
>= MAX_OBJECT_CLASSIFICATIONS
):
return
now = datetime.datetime.now().timestamp()
x, y, x2, y2 = calculate_region(
frame.shape,
@ -427,7 +441,7 @@ class CustomObjectClassificationProcessor(RealTimeProcessorApi):
write_classification_attempt(
self.train_dir,
cv2.cvtColor(crop, cv2.COLOR_RGB2BGR),
obj_data["id"],
object_id,
now,
"unknown",
0.0,
@ -448,7 +462,7 @@ class CustomObjectClassificationProcessor(RealTimeProcessorApi):
write_classification_attempt(
self.train_dir,
cv2.cvtColor(crop, cv2.COLOR_RGB2BGR),
obj_data["id"],
object_id,
now,
self.labelmap[best_id],
score,
@ -461,7 +475,7 @@ class CustomObjectClassificationProcessor(RealTimeProcessorApi):
sub_label = self.labelmap[best_id]
consensus_label, consensus_score = self.get_weighted_score(
obj_data["id"], sub_label, score, now
object_id, sub_label, score, now
)
if consensus_label is not None:
@ -470,7 +484,7 @@ class CustomObjectClassificationProcessor(RealTimeProcessorApi):
== ObjectClassificationType.sub_label
):
self.sub_label_publisher.publish(
(obj_data["id"], consensus_label, consensus_score),
(object_id, consensus_label, consensus_score),
EventMetadataTypeEnum.sub_label,
)
elif (
@ -479,7 +493,7 @@ class CustomObjectClassificationProcessor(RealTimeProcessorApi):
):
self.sub_label_publisher.publish(
(
obj_data["id"],
object_id,
self.model_config.name,
consensus_label,
consensus_score,

View File

@ -11,7 +11,6 @@ import {
FrigateConfig,
} from "@/types/frigateConfig";
import { useEffect, useMemo, useState } from "react";
import { isMobile } from "react-device-detect";
import { useTranslation } from "react-i18next";
import { FaFolderPlus } from "react-icons/fa";
import { MdModelTraining } from "react-icons/md";
@ -131,7 +130,7 @@ export default function ModelSelectionView({
</Button>
</div>
</div>
<div className="flex size-full gap-2 p-2">
<div className="grid auto-rows-max grid-cols-2 gap-2 overflow-y-auto p-2 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 2xl:grid-cols-8 3xl:grid-cols-10">
{selectedClassificationConfigs.length === 0 ? (
<NoModelsView
onCreateModel={() => setNewModel(true)}
@ -208,14 +207,13 @@ function ModelCard({ config, onClick }: ModelCardProps) {
<div
key={config.name}
className={cn(
"relative size-60 cursor-pointer overflow-hidden rounded-lg",
"relative aspect-square w-full cursor-pointer overflow-hidden rounded-lg",
"outline-transparent duration-500",
isMobile && "w-full",
)}
onClick={() => onClick()}
>
<img
className={cn("size-full", isMobile && "w-full")}
className="size-full"
src={`${baseUrl}clips/${config.name}/dataset/${coverImage?.name}/${coverImage?.img}`}
/>
<ImageShadowOverlay />