refactor(slide,det): 重构目标检测引擎并统一图像输入类型为 DynamicImage以及滑块匹配与比较引擎为 Rust 实现
- 统一 `predict` 和 `get_bbox` 接口参数为 `&DynamicImage`,消除多步处理时的重复图像解码开销。 - 引入轻量级 `DetectionResult` 结构体和固定大小数组 `[f32; 6]` 替代旧的嵌套 `Vec`,彻底消除后处理中的内存碎片。 - 优化 `preproc` 预处理逻辑,使用连续内存切片批量操作替代原有的逐像素迭代遍历。 - 移除多余的 `multiclass_nms_class_agnostic` 转发层,合并并精简 NMS 聚合函数。 - 优化 `calculate_center` 几何中心点计算函数,提高泛型语义并复用于两种匹配模式 - 在执行核心算法前增加尺寸与通道边界守卫(Guard Clauses),提升库的防防御性编程能力与崩溃安全性 - 移除多余的错误二次包装(map_err),改由 Rust 原生 Result 错误传播机制直接向上层抛出
This commit is contained in:
@@ -27,7 +27,7 @@ impl Slide {
|
||||
Self
|
||||
}
|
||||
|
||||
/// 对应 Python: slide_match
|
||||
/// 对应 Python: slide_match 滑块匹配接口
|
||||
pub fn slide_match(
|
||||
&self,
|
||||
target_image: &DynamicImage,
|
||||
@@ -38,9 +38,8 @@ impl Slide {
|
||||
let background_array = image_to_ndarray(background_image);
|
||||
|
||||
self.perform_slide_match(target_array.view(), background_array.view(), simple_target)
|
||||
.map_err(|e| anyhow!("滑块匹配失败: {}", e))
|
||||
}
|
||||
/// 对应 Python: slide_comparison
|
||||
/// 对应 Python: slide_comparison 差异比较接口
|
||||
/// 用于比较带坑位的图片与原始背景图,定位差异点
|
||||
pub fn slide_comparison(
|
||||
&self,
|
||||
@@ -53,7 +52,6 @@ impl Slide {
|
||||
|
||||
// 2. 执行比较逻辑 (对应 _perform_slide_comparison)
|
||||
self.perform_slide_comparison(target_array.view(), background_array.view())
|
||||
.map_err(|e| anyhow!("滑块比较执行失败: {}", e))
|
||||
}
|
||||
/// 对应 Python: _perform_slide_comparison
|
||||
pub fn perform_slide_comparison(
|
||||
@@ -61,7 +59,7 @@ impl Slide {
|
||||
target: ArrayView3<u8>,
|
||||
background: ArrayView3<u8>,
|
||||
) -> Result<SlideResult> {
|
||||
let (h, w, _) = target.dim();
|
||||
// let (h, w, _) = target.dim();
|
||||
|
||||
// 1. 计算图像差异并灰度化 (对应 cv2.absdiff + cv2.cvtColor)
|
||||
// 使用 OpenCV 标准权重公式:0.299R + 0.587G + 0.114B
|
||||
@@ -77,6 +75,26 @@ impl Slide {
|
||||
// }
|
||||
// }
|
||||
// 1. 计算差异数组 (复用 cv2::absdiff)
|
||||
|
||||
let (th, tw, tc) = target.dim();
|
||||
let (bh, bw, bc) = background.dim();
|
||||
|
||||
// 1. 比较模式下的严格尺寸校验
|
||||
if th != bh || tw != bw || tc != bc {
|
||||
return Err(anyhow!(
|
||||
"比较模式要求两张图分辨率与通道数完全一致!Target: [{}x{}x{}], Background: [{}x{}x{}]",
|
||||
tw,
|
||||
th,
|
||||
tc,
|
||||
bw,
|
||||
bh,
|
||||
bc
|
||||
));
|
||||
}
|
||||
if th == 0 || tw == 0 {
|
||||
return Err(anyhow!("输入图像尺寸不能为0"));
|
||||
}
|
||||
|
||||
let diff_array = abs_diff(&target, &background);
|
||||
|
||||
// 2. 转换为灰度数组 (复用你的 cv2.cvtColor)
|
||||
@@ -130,6 +148,30 @@ impl Slide {
|
||||
background: ArrayView3<u8>,
|
||||
simple_target: bool, // 增加这个参数
|
||||
) -> Result<SlideResult> {
|
||||
let (th, tw, tc) = target.dim();
|
||||
let (bh, bw, bc) = background.dim();
|
||||
|
||||
// 1. 严格的鲁棒性校验(防止底层的 imageproc 算子崩溃)
|
||||
if th == 0 || tw == 0 || bh == 0 || bw == 0 {
|
||||
return Err(anyhow!("输入图像的宽度或高度不能为0"));
|
||||
}
|
||||
if th > bh || tw > bw {
|
||||
return Err(anyhow!(
|
||||
"尺寸不匹配:滑块模板(target)尺寸 [{}x{}] 不能大于背景图(background) [{}x{}]",
|
||||
tw,
|
||||
th,
|
||||
bw,
|
||||
bh
|
||||
));
|
||||
}
|
||||
if tc != bc {
|
||||
return Err(anyhow!(
|
||||
"目标图与背景图的通道数不一致 (target: {}, bg: {})",
|
||||
tc,
|
||||
bc
|
||||
));
|
||||
}
|
||||
|
||||
// 1. 统一灰度化
|
||||
let target_gray = rgb_to_gray(target);
|
||||
let background_gray = rgb_to_gray(background);
|
||||
|
||||
Reference in New Issue
Block a user