"""
robust
案C: 最高ロバスト型の線検出
Black-hat + 適応的閾値の二重正規化に加え,
RANSAC で外れ値を除去する最もロバストな構成
"""
import cv2
import numpy as np
from common.vision.line_detector import (
ImageParams,
LineDetectResult,
fit_row_centers,
)
from common.vision.morphology import (
apply_dist_mask,
apply_iso_closing,
apply_width_filter,
)
def detect_robust(
frame: np.ndarray, params: ImageParams,
) -> LineDetectResult:
"""案C: 最高ロバスト型"""
# Black-hat 変換
bh_k = params.blackhat_ksize | 1
bh_kernel = cv2.getStructuringElement(
cv2.MORPH_ELLIPSE, (bh_k, bh_k),
)
blackhat = cv2.morphologyEx(
frame, cv2.MORPH_BLACKHAT, bh_kernel,
)
# 適応的閾値(BINARY: Black-hat 後は線が白)
block = max(params.adaptive_block | 1, 3)
binary = cv2.adaptiveThreshold(
blackhat, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY,
block, -params.adaptive_c,
)
# 等方クロージング + 距離変換マスク + 幅フィルタ
binary = apply_iso_closing(
binary, params.iso_close_size,
)
binary = apply_dist_mask(
binary, params.dist_thresh,
)
if params.width_near > 0 and params.width_far > 0:
binary = apply_width_filter(
binary,
params.width_near,
params.width_far,
params.width_tolerance,
)
# 行ごと中央値抽出 + RANSAC フィッティング
return fit_row_centers(
binary, params.min_line_width,
use_median=True,
ransac_thresh=params.ransac_thresh,
ransac_iter=params.ransac_iter,
median_ksize=params.median_ksize,
neighbor_thresh=params.neighbor_thresh,
residual_thresh=params.residual_thresh,
)