Initial commit
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import numpy as np
|
||||
from skimage.feature import local_binary_pattern
|
||||
|
||||
|
||||
def _downsample(gray_image: np.ndarray, binary_mask: np.ndarray | None = None, max_side: int = 96) -> tuple[np.ndarray, np.ndarray | None]:
|
||||
working = gray_image
|
||||
mask = binary_mask
|
||||
max_dim = max(working.shape[:2])
|
||||
if max_dim <= max_side:
|
||||
return working, mask
|
||||
step = int(np.ceil(max_dim / max_side))
|
||||
working = working[::step, ::step]
|
||||
if mask is not None:
|
||||
mask = mask[::step, ::step]
|
||||
return working, mask
|
||||
|
||||
|
||||
def texture_lbp_features(gray_image: np.ndarray, binary_mask: np.ndarray | None = None) -> dict[str, float]:
|
||||
gray_image, binary_mask = _downsample(gray_image, binary_mask)
|
||||
working = np.clip(gray_image, 0, 255).astype(np.uint8, copy=False)
|
||||
lbp_r1 = local_binary_pattern(working, P=8, R=1, method="uniform")
|
||||
lbp_r2 = local_binary_pattern(working, P=16, R=2, method="uniform")
|
||||
|
||||
if binary_mask is None:
|
||||
values_r1 = lbp_r1.ravel()
|
||||
values_r2 = lbp_r2.ravel()
|
||||
else:
|
||||
values_r1 = lbp_r1[binary_mask]
|
||||
values_r2 = lbp_r2[binary_mask]
|
||||
if values_r1.size == 0:
|
||||
values_r1 = lbp_r1.ravel()
|
||||
values_r2 = lbp_r2.ravel()
|
||||
|
||||
hist_r1, _ = np.histogram(values_r1, bins=np.arange(0, 8 + 3), density=True)
|
||||
hist_r2, _ = np.histogram(values_r2, bins=np.arange(0, 16 + 3), density=True)
|
||||
|
||||
features: dict[str, float] = {}
|
||||
for idx, value in enumerate(hist_r1):
|
||||
features[f"texture_lbp_r1_bin_{idx:02d}"] = float(value)
|
||||
for idx, value in enumerate(hist_r2):
|
||||
features[f"texture_lbp_r2_bin_{idx:02d}"] = float(value)
|
||||
return features
|
||||
Reference in New Issue
Block a user