mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-05-09 15:05:26 +03:00
Compare commits
No commits in common. "a2639b54bdf802382ff6f52e3a3cebd4694b5556" and "44c92e84cd6ad4ad68efb06c1546359c21340243" have entirely different histories.
a2639b54bd
...
44c92e84cd
@ -374,19 +374,9 @@ Use `match_distance` to allow small character mismatches. Alternatively, define
|
|||||||
|
|
||||||
Start with ["Why isn't my license plate being detected and recognized?"](#why-isnt-my-license-plate-being-detected-and-recognized). If you are still having issues, work through these steps.
|
Start with ["Why isn't my license plate being detected and recognized?"](#why-isnt-my-license-plate-being-detected-and-recognized). If you are still having issues, work through these steps.
|
||||||
|
|
||||||
1. Start with a simplified LPR config.
|
1. Enable debug logs to see exactly what Frigate is doing.
|
||||||
|
|
||||||
- Remove or comment out everything in your LPR config, including `min_area`, `min_plate_length`, `format`, `known_plates`, or `enhancement` values so that the only values left are `enabled` and `debug_save_plates`. This will run LPR with Frigate's default values.
|
- Enable debug logs for LPR by adding `frigate.data_processing.common.license_plate: debug` to your `logger` configuration. These logs are _very_ verbose, so only keep this enabled when necessary.
|
||||||
|
|
||||||
```yaml
|
|
||||||
lpr:
|
|
||||||
enabled: true
|
|
||||||
debug_save_plates: true
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Enable debug logs to see exactly what Frigate is doing.
|
|
||||||
|
|
||||||
- Enable debug logs for LPR by adding `frigate.data_processing.common.license_plate: debug` to your `logger` configuration. These logs are _very_ verbose, so only keep this enabled when necessary. Restart Frigate after this change.
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
logger:
|
logger:
|
||||||
@ -395,7 +385,7 @@ Start with ["Why isn't my license plate being detected and recognized?"](#why-is
|
|||||||
frigate.data_processing.common.license_plate: debug
|
frigate.data_processing.common.license_plate: debug
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Ensure your plates are being _detected_.
|
2. Ensure your plates are being _detected_.
|
||||||
|
|
||||||
If you are using a Frigate+ or `license_plate` detecting model:
|
If you are using a Frigate+ or `license_plate` detecting model:
|
||||||
|
|
||||||
@ -408,7 +398,7 @@ Start with ["Why isn't my license plate being detected and recognized?"](#why-is
|
|||||||
- Watch the debug logs for messages from the YOLOv9 plate detector.
|
- Watch the debug logs for messages from the YOLOv9 plate detector.
|
||||||
- You may need to adjust your `detection_threshold` if your plates are not being detected.
|
- You may need to adjust your `detection_threshold` if your plates are not being detected.
|
||||||
|
|
||||||
4. Ensure the characters on detected plates are being _recognized_.
|
3. Ensure the characters on detected plates are being _recognized_.
|
||||||
|
|
||||||
- Enable `debug_save_plates` to save images of detected text on plates to the clips directory (`/media/frigate/clips/lpr`). Ensure these images are readable and the text is clear.
|
- Enable `debug_save_plates` to save images of detected text on plates to the clips directory (`/media/frigate/clips/lpr`). Ensure these images are readable and the text is clear.
|
||||||
- Watch the debug view to see plates recognized in real-time. For non-dedicated LPR cameras, the `car` or `motorcycle` label will change to the recognized plate when LPR is enabled and working.
|
- Watch the debug view to see plates recognized in real-time. For non-dedicated LPR cameras, the `car` or `motorcycle` label will change to the recognized plate when LPR is enabled and working.
|
||||||
|
|||||||
@ -135,7 +135,6 @@ Finally, configure [hardware object detection](/configuration/object_detectors#h
|
|||||||
### MemryX MX3
|
### MemryX MX3
|
||||||
|
|
||||||
The MemryX MX3 Accelerator is available in the M.2 2280 form factor (like an NVMe SSD), and supports a variety of configurations:
|
The MemryX MX3 Accelerator is available in the M.2 2280 form factor (like an NVMe SSD), and supports a variety of configurations:
|
||||||
|
|
||||||
- x86 (Intel/AMD) PCs
|
- x86 (Intel/AMD) PCs
|
||||||
- Raspberry Pi 5
|
- Raspberry Pi 5
|
||||||
- Orange Pi 5 Plus/Max
|
- Orange Pi 5 Plus/Max
|
||||||
@ -143,6 +142,7 @@ The MemryX MX3 Accelerator is available in the M.2 2280 form factor (like an NVM
|
|||||||
|
|
||||||
#### Configuration
|
#### Configuration
|
||||||
|
|
||||||
|
|
||||||
#### Installation
|
#### Installation
|
||||||
|
|
||||||
To get started with MX3 hardware setup for your system, refer to the [Hardware Setup Guide](https://developer.memryx.com/get_started/hardware_setup.html).
|
To get started with MX3 hardware setup for your system, refer to the [Hardware Setup Guide](https://developer.memryx.com/get_started/hardware_setup.html).
|
||||||
@ -173,7 +173,7 @@ In your `docker-compose.yml`, also add:
|
|||||||
privileged: true
|
privileged: true
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
- /run/mxa_manager:/run/mxa_manager
|
/run/mxa_manager:/run/mxa_manager
|
||||||
```
|
```
|
||||||
|
|
||||||
If you can't use Docker Compose, you can run the container with something similar to this:
|
If you can't use Docker Compose, you can run the container with something similar to this:
|
||||||
@ -411,7 +411,7 @@ To install make sure you have the [community app plugin here](https://forums.unr
|
|||||||
|
|
||||||
## Proxmox
|
## Proxmox
|
||||||
|
|
||||||
[According to Proxmox documentation](https://pve.proxmox.com/pve-docs/pve-admin-guide.html#chapter_pct) it is recommended that you run application containers like Frigate inside a Proxmox QEMU VM. This will give you all the advantages of application containerization, while also providing the benefits that VMs offer, such as strong isolation from the host and the ability to live-migrate, which otherwise isn’t possible with containers. Ensure that ballooning is **disabled**, especially if you are passing through a GPU to the VM.
|
[According to Proxmox documentation](https://pve.proxmox.com/pve-docs/pve-admin-guide.html#chapter_pct) it is recommended that you run application containers like Frigate inside a Proxmox QEMU VM. This will give you all the advantages of application containerization, while also providing the benefits that VMs offer, such as strong isolation from the host and the ability to live-migrate, which otherwise isn’t possible with containers.
|
||||||
|
|
||||||
:::warning
|
:::warning
|
||||||
|
|
||||||
|
|||||||
@ -52,7 +52,6 @@
|
|||||||
},
|
},
|
||||||
"selected_one": "{{count}} selected",
|
"selected_one": "{{count}} selected",
|
||||||
"selected_other": "{{count}} selected",
|
"selected_other": "{{count}} selected",
|
||||||
"select_all": "All",
|
|
||||||
"camera": "Camera",
|
"camera": "Camera",
|
||||||
"detected": "detected",
|
"detected": "detected",
|
||||||
"normalActivity": "Normal",
|
"normalActivity": "Normal",
|
||||||
|
|||||||
@ -29,7 +29,6 @@
|
|||||||
},
|
},
|
||||||
"train": {
|
"train": {
|
||||||
"title": "Recent Recognitions",
|
"title": "Recent Recognitions",
|
||||||
"titleShort": "Recent",
|
|
||||||
"aria": "Select recent recognitions",
|
"aria": "Select recent recognitions",
|
||||||
"empty": "There are no recent face recognition attempts"
|
"empty": "There are no recent face recognition attempts"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import {
|
|||||||
} from "@/types/classification";
|
} from "@/types/classification";
|
||||||
import { Event } from "@/types/event";
|
import { Event } from "@/types/event";
|
||||||
import { forwardRef, useMemo, useRef, useState } from "react";
|
import { forwardRef, useMemo, useRef, useState } from "react";
|
||||||
import { isDesktop, isIOS, isMobile, isMobileOnly } from "react-device-detect";
|
import { isDesktop, isMobile, isMobileOnly } from "react-device-detect";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import TimeAgo from "../dynamic/TimeAgo";
|
import TimeAgo from "../dynamic/TimeAgo";
|
||||||
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
|
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
|
||||||
@ -127,15 +127,6 @@ export const ClassificationCard = forwardRef<
|
|||||||
imgClassName,
|
imgClassName,
|
||||||
isMobile && "w-full",
|
isMobile && "w-full",
|
||||||
)}
|
)}
|
||||||
style={
|
|
||||||
isIOS
|
|
||||||
? {
|
|
||||||
WebkitUserSelect: "none",
|
|
||||||
WebkitTouchCallout: "none",
|
|
||||||
}
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
draggable={false}
|
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
onLoad={() => setImageLoaded(true)}
|
onLoad={() => setImageLoaded(true)}
|
||||||
src={`${baseUrl}${data.filepath}`}
|
src={`${baseUrl}${data.filepath}`}
|
||||||
|
|||||||
@ -22,15 +22,11 @@ type SearchActionGroupProps = {
|
|||||||
selectedObjects: string[];
|
selectedObjects: string[];
|
||||||
setSelectedObjects: (ids: string[]) => void;
|
setSelectedObjects: (ids: string[]) => void;
|
||||||
pullLatestData: () => void;
|
pullLatestData: () => void;
|
||||||
onSelectAllObjects: () => void;
|
|
||||||
totalItems: number;
|
|
||||||
};
|
};
|
||||||
export default function SearchActionGroup({
|
export default function SearchActionGroup({
|
||||||
selectedObjects,
|
selectedObjects,
|
||||||
setSelectedObjects,
|
setSelectedObjects,
|
||||||
pullLatestData,
|
pullLatestData,
|
||||||
onSelectAllObjects,
|
|
||||||
totalItems,
|
|
||||||
}: SearchActionGroupProps) {
|
}: SearchActionGroupProps) {
|
||||||
const { t } = useTranslation(["components/filter"]);
|
const { t } = useTranslation(["components/filter"]);
|
||||||
const isAdmin = useIsAdmin();
|
const isAdmin = useIsAdmin();
|
||||||
@ -128,17 +124,6 @@ export default function SearchActionGroup({
|
|||||||
>
|
>
|
||||||
{t("button.unselect", { ns: "common" })}
|
{t("button.unselect", { ns: "common" })}
|
||||||
</div>
|
</div>
|
||||||
{selectedObjects.length < totalItems && (
|
|
||||||
<>
|
|
||||||
<div className="p-1">{"|"}</div>
|
|
||||||
<div
|
|
||||||
className="cursor-pointer p-2 text-primary hover:rounded-lg hover:bg-secondary"
|
|
||||||
onClick={onSelectAllObjects}
|
|
||||||
>
|
|
||||||
{t("select_all", { ns: "views/events" })}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
{isAdmin && (
|
{isAdmin && (
|
||||||
<div className="flex items-center gap-1 md:gap-2">
|
<div className="flex items-center gap-1 md:gap-2">
|
||||||
|
|||||||
@ -52,7 +52,7 @@ import {
|
|||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { isDesktop, isMobileOnly } from "react-device-detect";
|
import { isDesktop } from "react-device-detect";
|
||||||
import { Trans, useTranslation } from "react-i18next";
|
import { Trans, useTranslation } from "react-i18next";
|
||||||
import {
|
import {
|
||||||
LuFolderCheck,
|
LuFolderCheck,
|
||||||
@ -370,10 +370,10 @@ export default function FaceLibrary() {
|
|||||||
/>
|
/>
|
||||||
{selectedFaces?.length > 0 ? (
|
{selectedFaces?.length > 0 ? (
|
||||||
<div className="flex items-center justify-center gap-2">
|
<div className="flex items-center justify-center gap-2">
|
||||||
<div className="mx-1 flex w-auto items-center justify-center text-sm text-muted-foreground">
|
<div className="mx-1 flex w-48 items-center justify-center text-sm text-muted-foreground">
|
||||||
<div className="p-1">
|
<div className="p-1">
|
||||||
{t("selected", {
|
{t("selected", {
|
||||||
ns: "views/events",
|
ns: "views/event",
|
||||||
count: selectedFaces.length,
|
count: selectedFaces.length,
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
@ -384,24 +384,6 @@ export default function FaceLibrary() {
|
|||||||
>
|
>
|
||||||
{t("button.unselect", { ns: "common" })}
|
{t("button.unselect", { ns: "common" })}
|
||||||
</div>
|
</div>
|
||||||
{selectedFaces.length <
|
|
||||||
(pageToggle === "train"
|
|
||||||
? trainImages.length
|
|
||||||
: faceImages.length) && (
|
|
||||||
<>
|
|
||||||
<div className="p-1">{"|"}</div>
|
|
||||||
<div
|
|
||||||
className="cursor-pointer p-2 text-primary hover:rounded-lg hover:bg-secondary"
|
|
||||||
onClick={() =>
|
|
||||||
setSelectedFaces([
|
|
||||||
...(pageToggle === "train" ? trainImages : faceImages),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{t("select_all", { ns: "views/events" })}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
className="flex gap-2"
|
className="flex gap-2"
|
||||||
@ -500,18 +482,6 @@ function LibrarySelector({
|
|||||||
[renameFace],
|
[renameFace],
|
||||||
);
|
);
|
||||||
|
|
||||||
const pageTitle = useMemo(() => {
|
|
||||||
if (pageToggle != "train") {
|
|
||||||
return pageToggle;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isMobileOnly) {
|
|
||||||
return t("train.titleShort");
|
|
||||||
}
|
|
||||||
|
|
||||||
return t("train.title");
|
|
||||||
}, [pageToggle, t]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Dialog
|
<Dialog
|
||||||
@ -562,7 +532,7 @@ function LibrarySelector({
|
|||||||
<DropdownMenu modal={false}>
|
<DropdownMenu modal={false}>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button className="flex justify-between smart-capitalize">
|
<Button className="flex justify-between smart-capitalize">
|
||||||
{pageTitle}
|
{pageToggle == "train" ? t("train.title") : pageToggle}
|
||||||
<span className="ml-2 text-primary-variant">
|
<span className="ml-2 text-primary-variant">
|
||||||
({(pageToggle && faceData?.[pageToggle]?.length) || 0})
|
({(pageToggle && faceData?.[pageToggle]?.length) || 0})
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@ -421,10 +421,10 @@ export default function ModelTrainingView({ model }: ModelTrainingViewProps) {
|
|||||||
isMobileOnly && "justify-between",
|
isMobileOnly && "justify-between",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex w-auto items-center justify-center text-sm text-muted-foreground md:w-auto">
|
<div className="flex w-48 items-center justify-center text-sm text-muted-foreground">
|
||||||
<div className="p-1">
|
<div className="p-1">
|
||||||
{t("selected", {
|
{t("selected", {
|
||||||
ns: "views/events",
|
ns: "views/event",
|
||||||
count: selectedImages.length,
|
count: selectedImages.length,
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
@ -435,26 +435,6 @@ export default function ModelTrainingView({ model }: ModelTrainingViewProps) {
|
|||||||
>
|
>
|
||||||
{t("button.unselect", { ns: "common" })}
|
{t("button.unselect", { ns: "common" })}
|
||||||
</div>
|
</div>
|
||||||
{selectedImages.length <
|
|
||||||
(pageToggle === "train"
|
|
||||||
? trainImages?.length || 0
|
|
||||||
: dataset?.[pageToggle]?.length || 0) && (
|
|
||||||
<>
|
|
||||||
<div className="p-1">{"|"}</div>
|
|
||||||
<div
|
|
||||||
className="cursor-pointer p-2 text-primary hover:rounded-lg hover:bg-secondary"
|
|
||||||
onClick={() =>
|
|
||||||
setSelectedImages([
|
|
||||||
...(pageToggle === "train"
|
|
||||||
? trainImages || []
|
|
||||||
: dataset?.[pageToggle] || []),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{t("select_all", { ns: "views/events" })}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
className="flex gap-2"
|
className="flex gap-2"
|
||||||
|
|||||||
@ -572,8 +572,6 @@ export default function SearchView({
|
|||||||
selectedObjects={selectedObjects}
|
selectedObjects={selectedObjects}
|
||||||
setSelectedObjects={setSelectedObjects}
|
setSelectedObjects={setSelectedObjects}
|
||||||
pullLatestData={refresh}
|
pullLatestData={refresh}
|
||||||
onSelectAllObjects={onSelectAllObjects}
|
|
||||||
totalItems={uniqueResults.length}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user