Compare commits

...

6 Commits

Author SHA1 Message Date
Josh Hawkins
ce40c7912f memray tweaks 2025-12-19 10:26:17 -06:00
Josh Hawkins
459e9dc389 update memray docs 2025-12-19 10:24:34 -06:00
Josh Hawkins
b747c51aca add debug logs for individual lpr replace_rules 2025-12-19 09:13:17 -06:00
Josh Hawkins
abf16741a5 clarify object classification docs 2025-12-19 09:07:49 -06:00
Nicolas Mowen
853723795c Always mark model as untrained when a classname is changed 2025-12-19 07:54:17 -07:00
Josh Hawkins
73eceaf242 add cache key and activity indicator for loading classification wizard images 2025-12-19 08:39:35 -06:00
5 changed files with 54 additions and 22 deletions

View File

@ -95,6 +95,8 @@ The system will automatically generate example images from detected objects matc
When choosing which objects to classify, start with a small number of visually distinct classes and ensure your training samples match camera viewpoints and distances typical for those objects.
If examples for some of your classes do not appear in the grid, you can continue configuring the model without them. New images will begin to appear in the Recent Classifications view. When your missing classes are seen, classify them from this view and retrain your model.
### Improving the Model
- **Problem framing**: Keep classes visually distinct and relevant to the chosen object types.

View File

@ -9,8 +9,20 @@ Frigate includes built-in memory profiling using [memray](https://bloomberg.gith
Memory profiling is controlled via the `FRIGATE_MEMRAY_MODULES` environment variable. Set it to a comma-separated list of module names you want to profile:
```yaml
# docker-compose example
services:
frigate:
...
environment:
- FRIGATE_MEMRAY_MODULES=frigate.embeddings,frigate.capture
```
```bash
export FRIGATE_MEMRAY_MODULES="frigate.review_segment_manager,frigate.capture"
# docker run example
docker run -e FRIGATE_MEMRAY_MODULES="frigate.embeddings" \
...
--name frigate <frigate_image>
```
### Module Names
@ -24,11 +36,12 @@ Frigate processes are named using a module-based naming scheme. Common module na
- `frigate.output` - Output processing
- `frigate.audio_manager` - Audio processing
- `frigate.embeddings` - Embeddings processing
- `frigate.embeddings_manager` - Embeddings manager
You can also specify the full process name (including camera-specific identifiers) if you want to profile a specific camera:
```bash
export FRIGATE_MEMRAY_MODULES="frigate.capture:front_door"
FRIGATE_MEMRAY_MODULES=frigate.capture:front_door
```
When you specify a module name (e.g., `frigate.capture`), all processes with that module prefix will be profiled. For example, `frigate.capture` will profile all camera capture processes.
@ -55,11 +68,20 @@ After a process exits normally, you'll find HTML reports in `/config/memray_repo
If a process crashes or you want to generate a report from an existing binary file, you can manually create the HTML report:
- Run `memray` inside the Frigate container:
```bash
memray flamegraph /config/memray_reports/<module_name>.bin
docker-compose exec frigate memray flamegraph /config/memray_reports/<module_name>.bin
# or
docker exec -it <container_name_or_id> memray flamegraph /config/memray_reports/<module_name>.bin
```
This will generate an HTML file that you can open in your browser.
- You can also copy the `.bin` file to the host and run `memray` locally if you have it installed:
```bash
docker cp <container_name_or_id>:/config/memray_reports/<module_name>.bin /tmp/
memray flamegraph /tmp/<module_name>.bin
```
## Understanding the Reports
@ -110,20 +132,4 @@ The interactive HTML reports allow you to:
- Check that memray is properly installed (included by default in Frigate)
- Verify the process actually started and ran (check process logs)
## Example Usage
```bash
# Enable profiling for review and capture modules
export FRIGATE_MEMRAY_MODULES="frigate.review_segment_manager,frigate.capture"
# Start Frigate
# ... let it run for a while ...
# Check for reports
ls -lh /config/memray_reports/
# If a process crashed, manually generate report
memray flamegraph /config/memray_reports/frigate_capture_front_door.bin
```
For more information about memray and interpreting reports, see the [official memray documentation](https://bloomberg.github.io/memray/).

View File

@ -40,6 +40,7 @@ from frigate.util.classification import (
collect_state_classification_examples,
get_dataset_image_count,
read_training_metadata,
write_training_metadata,
)
from frigate.util.file import get_event_snapshot
@ -842,6 +843,12 @@ def rename_classification_category(
try:
os.rename(old_folder, new_folder)
# Mark dataset as ready to train by resetting training metadata
# This ensures the dataset is marked as changed after renaming
sanitized_name = sanitize_filename(name)
write_training_metadata(sanitized_name, 0)
return JSONResponse(
content=(
{

View File

@ -374,6 +374,9 @@ class LicensePlateProcessingMixin:
combined_plate = re.sub(
pattern, replacement, combined_plate
)
logger.debug(
f"{camera}: Processing replace rule: '{pattern}' -> '{replacement}', result: '{combined_plate}'"
)
except re.error as e:
logger.warning(
f"{camera}: Invalid regex in replace_rules '{pattern}': {e}"
@ -381,7 +384,7 @@ class LicensePlateProcessingMixin:
if combined_plate != original_combined:
logger.debug(
f"{camera}: Rules applied: '{original_combined}' -> '{combined_plate}'"
f"{camera}: All rules applied: '{original_combined}' -> '{combined_plate}'"
)
# Compute the combined area for qualifying boxes

View File

@ -45,6 +45,12 @@ export default function Step3ChooseExamples({
const [isProcessing, setIsProcessing] = useState(false);
const [currentClassIndex, setCurrentClassIndex] = useState(0);
const [selectedImages, setSelectedImages] = useState<Set<string>>(new Set());
const [cacheKey, setCacheKey] = useState<number>(Date.now());
const [loadedImages, setLoadedImages] = useState<Set<string>>(new Set());
const handleImageLoad = useCallback((imageName: string) => {
setLoadedImages((prev) => new Set(prev).add(imageName));
}, []);
const { data: trainImages, mutate: refreshTrainImages } = useSWR<string[]>(
hasGenerated ? `classification/${step1Data.modelName}/train` : null,
@ -332,6 +338,8 @@ export default function Step3ChooseExamples({
setHasGenerated(true);
toast.success(t("wizard.step3.generateSuccess"));
// Update cache key to force image reload
setCacheKey(Date.now());
await refreshTrainImages();
} catch (error) {
const axiosError = error as {
@ -565,10 +573,16 @@ export default function Step3ChooseExamples({
)}
onClick={() => toggleImageSelection(imageName)}
>
{!loadedImages.has(imageName) && (
<div className="flex h-full items-center justify-center">
<ActivityIndicator className="size-6" />
</div>
)}
<img
src={`${baseUrl}clips/${step1Data.modelName}/train/${imageName}`}
src={`${baseUrl}clips/${step1Data.modelName}/train/${imageName}?t=${cacheKey}`}
alt={`Example ${index + 1}`}
className="h-full w-full object-cover"
onLoad={() => handleImageLoad(imageName)}
/>
</div>
);