feat(core): 扩展 API、完善日志与代码文档规范

- 公开颜色过滤与字符集限制扩展 API,修复宏路径
- 库内打印替换为 tracing 日志,清理遗留废弃代码
- 补充核心逻辑单元测试与 crate 元数据
- 开启 missing_docs 并统一 rustfmt/clippy 格式
This commit is contained in:
2026-08-06 19:58:54 +08:00
parent 1362243f4e
commit fe61895926
20 changed files with 696 additions and 202 deletions

View File

@@ -1,8 +1,8 @@
//! 图像处理算法OpenCV 风格的常用函数封装。
use image::{imageops::FilterType, DynamicImage, GrayImage, ImageBuffer, Luma};
use image::{DynamicImage, GrayImage, ImageBuffer, Luma, imageops::FilterType};
use ndarray::{azip, Array2, Array3, ArrayView2, ArrayView3};
use ndarray::{Array2, Array3, ArrayView2, ArrayView3, azip};
use std::cmp::{max, min};
// 模拟openCV
@@ -12,7 +12,7 @@ pub fn abs_diff(a: &ArrayView3<u8>, b: &ArrayView3<u8>) -> Array3<u8> {
// 或者直接使用 zip_mut_with 处理以减少内存分配
let mut diff = Array3::zeros(a.dim());
azip!((res in &mut diff, &va in a, &vb in b) {
*res = (va as i16 - vb as i16).abs() as u8;
*res = va.abs_diff(vb);
});
diff
}
@@ -190,3 +190,43 @@ pub fn resize_image(
image.resize_exact(target_width, target_height, FilterType::Lanczos3)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn abs_diff_absolutes() {
let a = Array3::from_shape_vec((1, 1, 3), vec![10, 200, 5]).unwrap();
let b = Array3::from_shape_vec((1, 1, 3), vec![200, 100, 5]).unwrap();
let d = abs_diff(&a.view(), &b.view());
assert_eq!(d[[0, 0, 0]], 190);
assert_eq!(d[[0, 0, 1]], 100);
assert_eq!(d[[0, 0, 2]], 0);
}
#[test]
fn rgb_to_gray_white_is_255() {
let rgb = Array3::from_shape_vec((1, 1, 3), vec![255, 255, 255]).unwrap();
assert_eq!(rgb_to_gray(rgb.view())[[0, 0]], 255);
}
#[test]
fn min_max_loc_finds_max() {
let buf = ImageBuffer::<Luma<f32>, Vec<f32>>::from_fn(3, 2, |x, y| {
Luma([if x == 2 && y == 1 { 0.9 } else { 0.1 }])
});
let (val, loc) = min_max_loc(&buf);
assert_eq!(val, 0.9);
assert_eq!(loc, (2, 1));
}
#[test]
fn calculate_center_midpoint() {
assert_eq!(calculate_center((10, 20), 6, 4), (13, 22));
}
#[test]
fn rgb_to_opencv_hsv_red() {
assert_eq!(rgb_to_opencv_hsv(255, 0, 0), (0, 255, 255));
}
}