| from __future__ import annotations |
|
|
| import json |
| from pathlib import Path |
| import numpy as np |
|
|
|
|
| PARAMETER_NAMES = ("a1", "a2", "b1", "b2", "k_s", "k_m", "t1", "t2", "t_m") |
|
|
|
|
| def as_parameter_array(params): |
| if isinstance(params, dict): |
| if "params" in params: |
| params = params["params"] |
| else: |
| params = [params[name] for name in PARAMETER_NAMES] |
| params = np.asarray(params, dtype=np.float64).reshape(-1) |
| if len(params) == 11: |
| params = params[:9] |
| return params |
|
|
|
|
| def load_calibration(path, matcher=None): |
| with Path(path).open("r", encoding="utf-8") as handle: |
| payload = json.load(handle) |
|
|
| if matcher is not None: |
| payload = payload["matchers"][matcher] |
|
|
| return as_parameter_array(payload) |
|
|
|
|
| def confidence_risk(mconf): |
| return -np.log(np.clip(np.asarray(mconf, dtype=np.float64), 1e-8, 1.0)) |
|
|
|
|
| def fine_posterior_weights_from_params(params, std_c, std_f, mconf, err, H, W): |
| a1, a2, b1, b2, k_s, k_m, t1, t2, t_m = as_parameter_array(params) |
| std_c = np.asarray(std_c, dtype=np.float64) |
| std_f = np.asarray(std_f, dtype=np.float64) |
| mconf = np.asarray(mconf, dtype=np.float64).reshape(-1) |
| err = np.asarray(err, dtype=np.float64) |
| conf_term = k_m * (confidence_risk(mconf) - t_m) |
|
|
| std_c_norm_x = std_c[:, 0] / np.float64(W) * 100.0 |
| std_c_norm_y = std_c[:, 1] / np.float64(H) * 100.0 |
|
|
| alpha_x = 1.0 / (1.0 + np.exp(-(k_s * (std_c_norm_x - t1) + conf_term))) |
| alpha_y = 1.0 / (1.0 + np.exp(-(k_s * (std_c_norm_y - t2) + conf_term))) |
|
|
| scale_fine_x = np.maximum(np.sqrt(b1) * std_f[:, 0], 1e-6) |
| scale_fine_y = np.maximum(np.sqrt(b2) * std_f[:, 1], 1e-6) |
| scale_coarse_x = np.maximum(np.sqrt(a1) * std_c[:, 0], 1e-6) |
| scale_coarse_y = np.maximum(np.sqrt(a2) * std_c[:, 1], 1e-6) |
|
|
| log_fine_joint = ( |
| np.log(1.0 - alpha_x + 1e-8) |
| - np.abs(err[:, 0]) / scale_fine_x |
| - np.log(2.0 * scale_fine_x) |
| ) |
| log_coarse_joint = ( |
| np.log(alpha_x + 1e-8) |
| - np.abs(err[:, 0]) / scale_coarse_x |
| - np.log(2.0 * scale_coarse_x) |
| ) |
|
|
| log_fine_joint += ( |
| np.log(1.0 - alpha_y + 1e-8) |
| - np.abs(err[:, 1]) / scale_fine_y |
| - np.log(2.0 * scale_fine_y) |
| ) |
| log_coarse_joint += ( |
| np.log(alpha_y + 1e-8) |
| - np.abs(err[:, 1]) / scale_coarse_y |
| - np.log(2.0 * scale_coarse_y) |
| ) |
|
|
| return np.exp(log_fine_joint - np.logaddexp(log_fine_joint, log_coarse_joint)) |
|
|