* Don't return weighted name if it has the same number of results

* Remove link to incorrect format yolov9 models

* Fix command list from appearing when other inputs are focused

the description box in the tracked object details pane was causing the command input list to show when focused.

* clarify face docs

* Add note about python yolov9 export

* Check if hailort thread is still alive when timeout error is run into

* Reduce inference timeout

---------

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>
This commit is contained in:
Nicolas Mowen 2025-05-27 09:25:34 -06:00 committed by GitHub
parent 63f9689b0e
commit cbdac9ece5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 36 additions and 8 deletions

View File

@ -74,8 +74,10 @@ Fine-tune face recognition with these optional parameters at the global level of
## Usage ## Usage
Follow these steps to begin:
1. **Enable face recognition** in your configuration file and restart Frigate. 1. **Enable face recognition** in your configuration file and restart Frigate.
2. **Upload your face** using the **Add Face** button's wizard in the Face Library section of the Frigate UI. 2. **Upload one face** using the **Add Face** button's wizard in the Face Library section of the Frigate UI. Read below for the best practices on expanding your training set.
3. When Frigate detects and attempts to recognize a face, it will appear in the **Train** tab of the Face Library, along with its associated recognition confidence. 3. When Frigate detects and attempts to recognize a face, it will appear in the **Train** tab of the Face Library, along with its associated recognition confidence.
4. From the **Train** tab, you can **assign the face** to a new or existing person to improve recognition accuracy for the future. 4. From the **Train** tab, you can **assign the face** to a new or existing person to improve recognition accuracy for the future.

View File

@ -1053,13 +1053,14 @@ python3 yolo_to_onnx.py -m yolov7-320
#### YOLOv9 #### YOLOv9
YOLOv9 models can be exported using the below code or they [can be downloaded from hugging face](https://huggingface.co/Xenova/yolov9-onnx/tree/main) YOLOv9 models can be exported using the below code
```sh ```sh
git clone https://github.com/WongKinYiu/yolov9 git clone https://github.com/WongKinYiu/yolov9
cd yolov9 cd yolov9
# setup the virtual environment so installation doesn't affect main system # setup the virtual environment so installation doesn't affect main system
# NOTE: Virtual environment must be using Python 3.11 or older.
python3 -m venv ./ python3 -m venv ./
bin/pip install -r requirements.txt bin/pip install -r requirements.txt
bin/pip install onnx onnxruntime onnx-simplifier>=0.4.1 bin/pip install onnx onnxruntime onnx-simplifier>=0.4.1

View File

@ -471,17 +471,22 @@ class FaceRealTimeProcessor(RealTimeProcessorApi):
if not results_list: if not results_list:
return None, 0.0 return None, 0.0
weighted_scores = {} counts: dict[str, int] = {}
total_weights = {} weighted_scores: dict[str, int] = {}
total_weights: dict[str, int] = {}
for name, score, face_area in results_list: for name, score, face_area in results_list:
if name == "unknown": if name == "unknown":
continue continue
if name not in weighted_scores: if name not in weighted_scores:
counts[name] = 0
weighted_scores[name] = 0.0 weighted_scores[name] = 0.0
total_weights[name] = 0.0 total_weights[name] = 0.0
# increase count
counts[name] += 1
# Capped weight based on face area # Capped weight based on face area
weight = min(face_area, max_weight) weight = min(face_area, max_weight)
@ -494,6 +499,12 @@ class FaceRealTimeProcessor(RealTimeProcessorApi):
return None, 0.0 return None, 0.0
best_name = max(weighted_scores, key=weighted_scores.get) best_name = max(weighted_scores, key=weighted_scores.get)
# If the best name has the same number of results as another name, we are not confident it is a correct result
for name, count in counts.items():
if name != best_name and counts[best_name] == count:
return None, 0.0
weighted_average = weighted_scores[best_name] / total_weights[best_name] weighted_average = weighted_scores[best_name] / total_weights[best_name]
return best_name, weighted_average return best_name, weighted_average

View File

@ -345,11 +345,17 @@ class HailoDetector(DetectionApi):
request_id = self.input_store.put(tensor_input) request_id = self.input_store.put(tensor_input)
try: try:
_, infer_results = self.response_store.get(request_id, timeout=10.0) _, infer_results = self.response_store.get(request_id, timeout=1.0)
except TimeoutError: except TimeoutError:
logger.error( logger.error(
f"Timeout waiting for inference results for request {request_id}" f"Timeout waiting for inference results for request {request_id}"
) )
if not self.inference_thread.is_alive():
raise RuntimeError(
"HailoRT inference thread has stopped, restart required."
)
return np.zeros((20, 6), dtype=np.float32) return np.zeros((20, 6), dtype=np.float32)
if isinstance(infer_results, list) and len(infer_results) == 1: if isinstance(infer_results, list) and len(infer_results) == 1:

View File

@ -763,12 +763,18 @@ export default function InputWithTags({
{inputFocused ? ( {inputFocused ? (
<LuChevronUp <LuChevronUp
onClick={() => setInputFocused(false)} onClick={() => {
setInputFocused(false);
inputRef.current?.blur();
}}
className="size-4 cursor-pointer text-secondary-foreground" className="size-4 cursor-pointer text-secondary-foreground"
/> />
) : ( ) : (
<LuChevronDown <LuChevronDown
onClick={() => setInputFocused(true)} onClick={() => {
setInputFocused(true);
inputRef.current?.focus();
}}
className="size-4 cursor-pointer text-secondary-foreground" className="size-4 cursor-pointer text-secondary-foreground"
/> />
)} )}
@ -778,7 +784,9 @@ export default function InputWithTags({
<CommandList <CommandList
className={cn( className={cn(
"scrollbar-container border-t duration-200 animate-in fade-in", "scrollbar-container border-t duration-200 animate-in fade-in",
inputFocused ? "visible" : "hidden", inputFocused && inputRef.current?.matches(":focus")
? "visible"
: "hidden",
)} )}
> >
{!currentFilterType && inputValue && ( {!currentFilterType && inputValue && (