You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
5.1 KiB

3 months ago
import numpy as np
import json
from typing import Dict, Any
class CameraModel:
def __init__(self, config_path: str = None):
"""
初始化相机模型支持从配置文件加载参数
:param config_path: 配置文件的路径JSON/YAML如果为 None则使用默认参数
"""
# 默认参数
self._default_params = {
'camera_width': 1280,
'camera_height': 960,
"origin_K": np.array([[1086.58411235010, 0.00000000e+00, 656.379279306796],
[0.00000000e+00, 1086.65442545872, 960-489.101890262552],
[0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]),
"undistor_K": np.array([[838.19297892, 0, 658.51580973],
[0, 836.93529706, 960-484.42225009],
[0, 0, 1]]),
"dist_coeffs": np.array([-0.450688803, 0.260760637, 0.000210619624, -0.000669674309, -0.0447846385]),
"focal_length": 3.6,
3 months ago
"height": 1007.0633042608584, # 1.007e+03 - 9
"rotation_alpha": 0.8892272342384955,
"rotation_beta": 0.6786627929104145,
"position_offset_x": 507,
"position_offset_y": 32,
"rotation_camera": 0.03985022053087201,
"filter": True,
3 months ago
"filt_percent": 0.05,
3 months ago
"outlier_num": 10,
"ransac_residual_threshold": 2.5,
"grid_downsample": True,
3 months ago
"cell_size": 10,
3 months ago
"zoom":1.1,
3 months ago
3 months ago
}
# 如果提供了配置文件,则从文件加载参数
if config_path:
self.load_config(config_path)
else:
self._set_parameters(self._default_params)
def _set_parameters(self, params: Dict[str, Any]) -> None:
"""根据参数字典设置成员变量"""
self.camera_width = params["camera_width"]
self.camera_height = params["camera_height"]
self.origin_K = np.array(params["origin_K"])
self.undistor_K = np.array(params["undistor_K"])
self.dist_coeffs = np.array(params["dist_coeffs"])
self.focal_length = params["focal_length"]
self.height = params["height"]
self.rotation_alpha = params["rotation_alpha"]
self.rotation_beta = params["rotation_beta"]
self.position_offset_x = params["position_offset_x"]
self.position_offset_y = params["position_offset_y"]
self.rotation_camera = params["rotation_camera"]
3 months ago
self.filter = params["filter"]
3 months ago
self.filt_percent = params["filt_percent"]
3 months ago
self.outlier_num = params["outlier_num"]
3 months ago
self.ransac_residual_threshold = params["ransac_residual_threshold"]
3 months ago
self.grid_downsample = params["grid_downsample"]
self.cell_size = params["cell_size"]
3 months ago
self.zoom = params["zoom"]
3 months ago
# 计算派生属性
self.pixel_size_x = self.focal_length / self.undistor_K[0, 0]
self.pixel_size_y = self.focal_length / self.undistor_K[1, 1]
self.principal_point = (self.undistor_K[0, 2], self.undistor_K[1, 2])
def load_config(self, file_path: str) -> None:
"""从 JSON 文件加载参数"""
with open(file_path, 'r') as f:
params = json.load(f)
self._set_parameters(params)
def save_config(self, file_path: str) -> None:
"""将当前参数保存到 JSON 文件"""
params = {
"camera_width": self.camera_width,
"camera_height": self.camera_height,
"origin_K": self.origin_K.tolist(),
"undistor_K": self.undistor_K.tolist(),
"dist_coeffs": self.dist_coeffs.tolist(),
"focal_length": self.focal_length,
"height": self.height,
"rotation_alpha": self.rotation_alpha,
"rotation_beta": self.rotation_beta,
"position_offset_x": self.position_offset_x,
"position_offset_y": self.position_offset_y,
"rotation_camera": self.rotation_camera,
3 months ago
"filter": self.filter,
3 months ago
"filt_percent": self.filt_percent,
3 months ago
"outlier_num": self.outlier_num,
"grid_downsample": self.grid_downsample,
"cell_size": self.cell_size,
3 months ago
"ransac_residual_threshold": self.ransac_residual_threshold,
"zoom": self.zoom
3 months ago
}
with open(file_path, 'w') as f:
json.dump(params, f, indent=4)
def update_parameter(self, key: str, value: Any) -> None:
"""动态更新单个参数"""
if hasattr(self, key):
setattr(self, key, value)
# 如果修改了 K 或焦距,需要重新计算派生属性
if key in ["undistor_K", "focal_length"]:
self.pixel_size_x = self.focal_length / self.undistor_K[0, 0]
self.pixel_size_y = self.focal_length / self.undistor_K[1, 1]
self.principal_point = (self.undistor_K[0, 2], self.undistor_K[1, 2])
else:
raise AttributeError(f"参数 {key} 不存在")
3 months ago
# model = CameraModel(None)
# model.save_config("updated_config.json")