* fix i18n keys

* hide disable from context menu for viewers

* Fix auto live check for default dashboard and camera groups

Disabling the Automatic Live View switch in Settings should prevent streaming from occurring. Overriding any settings in a camera group will override the global setting. The check here incorrectly always returned false instead of undefined.

* clarify hardware accelerated enrichments

* clarify

* add note about detect stream to face rec docs

* add note about low end Dahuas for autotracking

* Catch invalid face box / image

* Video tab tweaks

With the changes in https://github.com/blakeblackshear/frigate/pull/18220, the video tab in the Tracked Object Details pane now correctly trims the in-browser HLS video. Because of keyframes and record/detect stream differences, we can manually subtract a couple of seconds from the event start_time to ensure the first few frames aren't cut off from the video

* Clarify

* Don't use Migraphx by default

* Provide better support for running embeddings on GPU

* correctly join cameras

* Adjust blur confidence reduction

---------

Co-authored-by: Nicolas Mowen <nickmowen213@gmail.com>
This commit is contained in:
Josh Hawkins
2025-06-03 06:33:32 -06:00
committed by GitHub
co-authored by Nicolas Mowen
parent af5a9e7634
commit dba9206898
15 changed files with 96 additions and 46 deletions
+19 -1
View File
@@ -154,7 +154,25 @@ def train_face(request: Request, name: str, body: dict = None):
x2 = x1 + int(face_box[2] * detect_config.width) - 4
y2 = y1 + int(face_box[3] * detect_config.height) - 4
face = snapshot[y1:y2, x1:x2]
cv2.imwrite(os.path.join(new_file_folder, new_name), face)
success = True
if face.size > 0:
try:
cv2.imwrite(os.path.join(new_file_folder, new_name), face)
success = True
except Exception:
pass
if not success:
return JSONResponse(
content=(
{
"success": False,
"message": "Invalid face box or no face exists",
}
),
status_code=404,
)
context: EmbeddingsContext = request.app.embeddings
context.clear_face_classifier()
+16 -16
View File
@@ -108,21 +108,21 @@ class FaceRecognizer(ABC):
image, M, (output_width, output_height), flags=cv2.INTER_CUBIC
)
def get_blur_factor(self, input: np.ndarray) -> float:
"""Calculates the factor for the confidence based on the blur of the image."""
def get_blur_confidence_reduction(self, input: np.ndarray) -> tuple[float, float]:
"""Calculates the reduction in confidence based on the blur of the image."""
if not self.config.face_recognition.blur_confidence_filter:
return 1.0
variance = cv2.Laplacian(input, cv2.CV_64F).var()
if variance < 60: # image is very blurry
return 0.96
elif variance < 70: # image moderately blurry
return 0.98
elif variance < 80: # image is slightly blurry
return 0.99
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
else:
return 1.0
return variance, 0.0
def similarity_to_confidence(
@@ -234,8 +234,8 @@ class FaceNetRecognizer(FaceRecognizer):
# face recognition is best run on grayscale images
# get blur factor before aligning face
blur_factor = self.get_blur_factor(face_image)
logger.debug(f"face detected with blurriness {blur_factor}")
variance, blur_reduction = self.get_blur_confidence_reduction(face_image)
logger.debug(f"face detected with blurriness {variance}")
# align face and run recognition
img = self.align_face(face_image, face_image.shape[1], face_image.shape[0])
@@ -258,7 +258,7 @@ class FaceNetRecognizer(FaceRecognizer):
score = confidence
label = name
return label, round(score * blur_factor, 2)
return label, round(score - blur_reduction, 2)
class ArcFaceRecognizer(FaceRecognizer):
@@ -344,9 +344,9 @@ class ArcFaceRecognizer(FaceRecognizer):
# face recognition is best run on grayscale images
# get blur factor before aligning face
blur_factor = self.get_blur_factor(face_image)
logger.debug(f"face detected with blurriness {blur_factor}")
# get blur reduction before aligning face
variance, blur_reduction = self.get_blur_confidence_reduction(face_image)
logger.debug(f"face detected with blurriness {variance}")
# align face and run recognition
img = self.align_face(face_image, face_image.shape[1], face_image.shape[0])
@@ -367,4 +367,4 @@ class ArcFaceRecognizer(FaceRecognizer):
score = confidence
label = name
return label, round(score * blur_factor, 2)
return label, round(score - blur_reduction, 2)
+7
View File
@@ -345,6 +345,13 @@ def get_ort_providers(
"device_type": device,
}
)
elif provider == "MIGraphXExecutionProvider":
# MIGraphX uses more CPU than ROCM, while also being the same speed
if device == "MIGraphX":
providers.append(provider)
options.append({})
else:
continue
elif provider == "CPUExecutionProvider":
providers.append(provider)
options.append(