feat: exposure detection (over/underexposed)
This commit is contained in:
18
analyzer.py
18
analyzer.py
@@ -1,5 +1,6 @@
|
|||||||
import cv2
|
import cv2
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
|
||||||
def is_blurry(path: str, threshold: float = 100.0) -> bool:
|
def is_blurry(path: str, threshold: float = 100.0) -> bool:
|
||||||
@@ -9,3 +10,20 @@ def is_blurry(path: str, threshold: float = 100.0) -> bool:
|
|||||||
return False
|
return False
|
||||||
variance = cv2.Laplacian(img, cv2.CV_64F).var()
|
variance = cv2.Laplacian(img, cv2.CV_64F).var()
|
||||||
return bool(variance < threshold)
|
return bool(variance < threshold)
|
||||||
|
|
||||||
|
|
||||||
|
def _mean_brightness(path: str) -> float:
|
||||||
|
"""Durchschnittliche Helligkeit eines Bildes (0-255)."""
|
||||||
|
img = Image.open(path).convert("L")
|
||||||
|
arr = np.array(img, dtype=np.float32)
|
||||||
|
return float(arr.mean())
|
||||||
|
|
||||||
|
|
||||||
|
def is_overexposed(path: str, threshold: float = 240.0) -> bool:
|
||||||
|
"""Gibt True zurueck, wenn das Bild ueberbelichtet ist."""
|
||||||
|
return _mean_brightness(path) > threshold
|
||||||
|
|
||||||
|
|
||||||
|
def is_underexposed(path: str, threshold: float = 30.0) -> bool:
|
||||||
|
"""Gibt True zurueck, wenn das Bild unterbelichtet ist."""
|
||||||
|
return _mean_brightness(path) < threshold
|
||||||
|
|||||||
@@ -25,3 +25,22 @@ def test_normal_image_is_not_blurry(tmp_path):
|
|||||||
p = tmp_path / "sharp.jpg"
|
p = tmp_path / "sharp.jpg"
|
||||||
img.save(p)
|
img.save(p)
|
||||||
assert is_blurry(str(p), threshold=100) is False
|
assert is_blurry(str(p), threshold=100) is False
|
||||||
|
|
||||||
|
|
||||||
|
from analyzer import is_overexposed, is_underexposed
|
||||||
|
|
||||||
|
|
||||||
|
def test_white_image_is_overexposed(tmp_path):
|
||||||
|
path = make_test_image(tmp_path, color=(255, 255, 255))
|
||||||
|
assert is_overexposed(path, threshold=240) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_dark_image_is_underexposed(tmp_path):
|
||||||
|
path = make_test_image(tmp_path, color=(10, 10, 10))
|
||||||
|
assert is_underexposed(path, threshold=30) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_normal_image_is_neither(tmp_path):
|
||||||
|
path = make_test_image(tmp_path, color=(128, 128, 128))
|
||||||
|
assert is_overexposed(path, threshold=240) is False
|
||||||
|
assert is_underexposed(path, threshold=30) is False
|
||||||
|
|||||||
Reference in New Issue
Block a user