mirror of
https://github.com/blakeblackshear/frigate.git
synced 2025-07-30 13:48:07 +02:00
Fixes (#18777)
* Remove tracked object update resets * Adjust face blur reduction * Add space for config editor buttons * Slight adjustment * Fix double thats * update icons --------- Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>
This commit is contained in:
parent
42cae5d9ee
commit
fe571dc217
@ -23,7 +23,7 @@ If you are using go2rtc, you should adjust the following settings in your camera
|
||||
|
||||
- Video codec: **H.264** - provides the most compatible video codec with all Live view technologies and browsers. Avoid any kind of "smart codec" or "+" codec like _H.264+_ or _H.265+_. as these non-standard codecs remove keyframes (see below).
|
||||
- Audio codec: **AAC** - provides the most compatible audio codec with all Live view technologies and browsers that support audio.
|
||||
- I-frame interval (sometimes called the keyframe interval, the interframe space, or the GOP length): match your camera's frame rate, or choose "1x" (for interframe space on Reolink cameras). For example, if your stream outputs 20fps, your i-frame interval should be 20 (or 1x on Reolink). Values higher than the frame rate will cause the stream to take longer to begin playback. See [this page](https://gardinal.net/understanding-the-keyframe-interval/) for more on keyframes. For many users this may not be an issue, but it should be noted that that a 1x i-frame interval will cause more storage utilization if you are using the stream for the `record` role as well.
|
||||
- I-frame interval (sometimes called the keyframe interval, the interframe space, or the GOP length): match your camera's frame rate, or choose "1x" (for interframe space on Reolink cameras). For example, if your stream outputs 20fps, your i-frame interval should be 20 (or 1x on Reolink). Values higher than the frame rate will cause the stream to take longer to begin playback. See [this page](https://gardinal.net/understanding-the-keyframe-interval/) for more on keyframes. For many users this may not be an issue, but it should be noted that a 1x i-frame interval will cause more storage utilization if you are using the stream for the `record` role as well.
|
||||
|
||||
The default video and audio codec on your camera may not always be compatible with your browser, which is why setting them to H.264 and AAC is recommended. See the [go2rtc docs](https://github.com/AlexxIT/go2rtc?tab=readme-ov-file#codecs-madness) for codec support information.
|
||||
|
||||
|
@ -108,21 +108,24 @@ class FaceRecognizer(ABC):
|
||||
image, M, (output_width, output_height), flags=cv2.INTER_CUBIC
|
||||
)
|
||||
|
||||
def get_blur_confidence_reduction(self, input: np.ndarray) -> tuple[float, float]:
|
||||
def get_blur_confidence_reduction(self, input: np.ndarray) -> float:
|
||||
"""Calculates the reduction in confidence based on the blur of the image."""
|
||||
if not self.config.face_recognition.blur_confidence_filter:
|
||||
return 0, 0.0
|
||||
return 0.0
|
||||
|
||||
variance = cv2.Laplacian(input, cv2.CV_64F).var()
|
||||
logger.debug(f"face detected with blurriness {variance}")
|
||||
|
||||
if variance < 80: # image is very blurry
|
||||
return variance, 0.05
|
||||
elif variance < 100: # image moderately blurry
|
||||
return variance, 0.03
|
||||
elif variance < 150: # image is slightly blurry
|
||||
return variance, 0.01
|
||||
if variance < 120: # image is very blurry
|
||||
return 0.06
|
||||
elif variance < 160: # image moderately blurry
|
||||
return 0.04
|
||||
elif variance < 200: # image is slightly blurry
|
||||
return 0.02
|
||||
elif variance < 250: # image is mostly clear
|
||||
return 0.01
|
||||
else:
|
||||
return variance, 0.0
|
||||
return 0.0
|
||||
|
||||
|
||||
def similarity_to_confidence(
|
||||
@ -234,8 +237,7 @@ class FaceNetRecognizer(FaceRecognizer):
|
||||
# face recognition is best run on grayscale images
|
||||
|
||||
# get blur factor before aligning face
|
||||
variance, blur_reduction = self.get_blur_confidence_reduction(face_image)
|
||||
logger.debug(f"face detected with blurriness {variance}")
|
||||
blur_reduction = self.get_blur_confidence_reduction(face_image)
|
||||
|
||||
# align face and run recognition
|
||||
img = self.align_face(face_image, face_image.shape[1], face_image.shape[0])
|
||||
@ -345,8 +347,7 @@ class ArcFaceRecognizer(FaceRecognizer):
|
||||
# face recognition is best run on grayscale images
|
||||
|
||||
# get blur reduction before aligning face
|
||||
variance, blur_reduction = self.get_blur_confidence_reduction(face_image)
|
||||
logger.debug(f"face detected with blurriness {variance}")
|
||||
blur_reduction = self.get_blur_confidence_reduction(face_image)
|
||||
|
||||
# align face and run recognition
|
||||
img = self.align_face(face_image, face_image.shape[1], face_image.shape[0])
|
||||
|
@ -1579,19 +1579,6 @@ class LicensePlateProcessingMixin:
|
||||
if object_id in self.camera_current_cars.get(camera, []):
|
||||
self.camera_current_cars[camera].remove(object_id)
|
||||
|
||||
if len(self.camera_current_cars[camera]) == 0:
|
||||
self.requestor.send_data(
|
||||
"tracked_object_update",
|
||||
json.dumps(
|
||||
{
|
||||
"type": TrackedObjectUpdateTypesEnum.lpr,
|
||||
"name": None,
|
||||
"plate": None,
|
||||
"camera": camera,
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class CTCDecoder:
|
||||
"""
|
||||
|
@ -444,18 +444,6 @@ class FaceRealTimeProcessor(RealTimeProcessorApi):
|
||||
if object_id in self.camera_current_people.get(camera, []):
|
||||
self.camera_current_people[camera].remove(object_id)
|
||||
|
||||
if len(self.camera_current_people[camera]) == 0:
|
||||
self.requestor.send_data(
|
||||
"tracked_object_update",
|
||||
json.dumps(
|
||||
{
|
||||
"type": TrackedObjectUpdateTypesEnum.face,
|
||||
"name": None,
|
||||
"camera": camera,
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
def weighted_average(
|
||||
self, results_list: list[tuple[str, float, int]], max_weight: int = 4000
|
||||
):
|
||||
|
@ -339,7 +339,7 @@
|
||||
"clickDrawPolygon": "Click to draw a polygon on the image.",
|
||||
"objects": {
|
||||
"title": "Objects",
|
||||
"desc": "The object type that that applies to this object mask.",
|
||||
"desc": "The object type that applies to this object mask.",
|
||||
"allObjectTypes": "All object types"
|
||||
},
|
||||
"toast": {
|
||||
|
@ -265,7 +265,7 @@ function ConfigEditor() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1 flex-col overflow-hidden">
|
||||
<div className="mt-2 flex flex-1 flex-col overflow-hidden">
|
||||
{error && (
|
||||
<div className="mt-2 max-h-[30%] min-h-[2.5rem] overflow-auto whitespace-pre-wrap border-2 border-muted bg-background_alt p-4 text-sm text-danger md:max-h-[40%]">
|
||||
{error}
|
||||
|
@ -26,11 +26,13 @@ import {
|
||||
GiDeer,
|
||||
GiFox,
|
||||
GiGoat,
|
||||
GiKangaroo,
|
||||
GiPolarBear,
|
||||
GiPostStamp,
|
||||
GiRabbit,
|
||||
GiRaccoonHead,
|
||||
GiSailboat,
|
||||
GiSquirrel,
|
||||
} from "react-icons/gi";
|
||||
import { LuBox, LuLassoSelect, LuScanBarcode } from "react-icons/lu";
|
||||
import * as LuIcons from "react-icons/lu";
|
||||
@ -72,6 +74,7 @@ export function getIconForLabel(label: string, className?: string) {
|
||||
case "boat":
|
||||
return <GiSailboat key={label} className={className} />;
|
||||
case "bus":
|
||||
case "school_bus":
|
||||
return <FaBus key={label} className={className} />;
|
||||
case "car":
|
||||
case "vehicle":
|
||||
@ -90,6 +93,8 @@ export function getIconForLabel(label: string, className?: string) {
|
||||
return <GiGoat key={label} className={className} />;
|
||||
case "horse":
|
||||
return <FaHorse key={label} className={className} />;
|
||||
case "kangaroo":
|
||||
return <GiKangaroo key={label} className={className} />;
|
||||
case "license_plate":
|
||||
return <LuScanBarcode key={label} className={className} />;
|
||||
case "motorcycle":
|
||||
@ -108,6 +113,8 @@ export function getIconForLabel(label: string, className?: string) {
|
||||
return <FaHockeyPuck key={label} className={className} />;
|
||||
case "sports_ball":
|
||||
return <FaFootballBall key={label} className={className} />;
|
||||
case "skunk":
|
||||
return <GiSquirrel key={label} className={className} />;
|
||||
case "squirrel":
|
||||
return <LuIcons.LuSquirrel key={label} className={className} />;
|
||||
case "umbrella":
|
||||
@ -127,12 +134,14 @@ export function getIconForLabel(label: string, className?: string) {
|
||||
case "amazon":
|
||||
return <FaAmazon key={label} className={className} />;
|
||||
case "an_post":
|
||||
case "canada_post":
|
||||
case "dpd":
|
||||
case "gls":
|
||||
case "nzpost":
|
||||
case "postnl":
|
||||
case "postnord":
|
||||
case "purolator":
|
||||
case "royal_mail":
|
||||
return <GiPostStamp key={label} className={className} />;
|
||||
case "dhl":
|
||||
return <FaDhl key={label} className={className} />;
|
||||
|
Loading…
Reference in New Issue
Block a user