Windows 和 Linux 上的 OpenCV 不同结果
OpenCV different results on Windows and Linux
我正在为基于 Rust 的 OpenCV 编写一个跨平台包装器。我写了几个测试来检查我的包装器是否正常工作。一些测试通过了,一些测试失败了,值略有不同,但一个测试的结果完全不同。
右边的数字是我在 windows 上得到的,左边的是我在 linux
上得到的
---- compare_hist_chi_square stdout ----
thread 'compare_hist_chi_square' panicked at '2697.981816285168 == 1360.7', tests/test_imgproc.rs:81:4
---- compare_hist_bhattacharyya stdout ----
thread 'compare_hist_bhattacharyya' panicked at '0.6798259690477988 == 0.6679', tests/test_imgproc.rs:81:4
---- compare_hist_chi_square_alternative stdout ----
thread 'compare_hist_chi_square_alternative' panicked at '41.65613074156445 == 41.027', tests/test_imgproc.rs:81:4
---- compare_hist_correlation stdout ----
thread 'compare_hist_correlation' panicked at '0.20456957916644988 == 0.211', tests/test_imgproc.rs:81:4
---- compare_hist_intersection stdout ----
thread 'compare_hist_intersection' panicked at '5.440850785933435 == 5.682', tests/test_imgproc.rs:81:4
---- compare_hist_kullback_leibler_divergence stdout ----
thread 'compare_hist_kullback_leibler_divergence' panicked at '55.71912075710992 == 54.06287', tests/test_imgproc.rs:81:4
我试图从 this article 重现代码。我拍摄了相同的图像并希望获得相同的结果。然而,这并没有发生。
这里是一些测试的Rust代码(仅供参考):
extern crate cv;
extern crate float_cmp;
mod utils;
use cv::*;
use cv::imgproc::*;
use float_cmp::ApproxEqRatio;
use utils::*;
#[test]
#[should_panic]
fn compare_hist_different_dimensions_panic() {
let first_image = load_unchanged("assets/Histogram_Comparison_Source_0.jpg");
let second_image = load_unchanged("assets/Histogram_Comparison_Source_1.jpg");
let _ = first_image.compare_hist(&second_image, HistogramComparisionMethod::Corellation).unwrap();
}
#[test]
fn compare_hist_correlation() {
compare_hist(HistogramComparisionMethod::Corellation, 0.211);
}
#[test]
fn compare_hist_chi_square() {
compare_hist(HistogramComparisionMethod::ChiSquare, 1360.7);
}
#[test]
fn compare_hist_intersection() {
compare_hist(HistogramComparisionMethod::Intersection, 5.682);
}
#[test]
fn compare_hist_bhattacharyya() {
compare_hist(HistogramComparisionMethod::Bhattacharyya, 0.6679);
}
#[test]
fn compare_hist_chi_square_alternative() {
compare_hist(HistogramComparisionMethod::ChiSquareAlternative, 41.027);
}
#[test]
fn compare_hist_kullback_leibler_divergence() {
compare_hist(
HistogramComparisionMethod::KullbackLeiblerDivergence,
54.06287,
);
}
fn compare_hist(method: HistogramComparisionMethod, expected_result: f64) {
let first_image = get_image_histogram("assets/Histogram_Comparison_Source_0.jpg");
let second_image = get_image_histogram("assets/Histogram_Comparison_Source_1.jpg");
let result = first_image.compare_hist(&second_image, method).unwrap();
assert_eq(result, expected_result);
}
fn get_image_histogram(path: &'static str) -> Mat {
let image = load_unchanged(path);
let image = image.cvt_color(ColorConversionCodes::BGR2HSV);
let hsize = [50, 60];
let h_ranges = [0_f32, 180_f32];
let s_ranges = [0_f32, 256_f32];
let ranges = [
h_ranges.as_ptr() as *const f32,
s_ranges.as_ptr() as *const f32,
];
let channels = [0, 1];
let image = image.calc_hist(
channels.as_ptr(),
Mat::new(),
2,
hsize.as_ptr(),
ranges.as_ptr(),
);
let image = image.normalize(0_f64, 1_f64, NormTypes::NormMinMax);
image
}
fn assert_eq(a: f64, b: f64) {
assert!(a.approx_eq_ratio(&b, 0.001), format!("{} == {}", a, b));
}
pub fn load_unchanged<P: AsRef<Path>>(img: P) -> Mat {
let buf = load_image_as_buf(img);
Mat::imdecode(&buf, ImreadModes::ImreadUnchanged)
}
fn load_image_as_buf<P: AsRef<Path>>(img: P) -> Vec<u8> {
let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
d.push(img);
let mut buf = Vec::new();
File::open(d).unwrap().read_to_end(&mut buf).unwrap();
buf
}
可能是因为 jpg
和不同平台的 jpg
读者不同,但它不能解释 2697.98
vs 1360.7
,几乎是 2 倍的差异!
这里可能出了什么问题? Here is my entire pull request 我正在尝试添加此功能的地方(小心,其中包含一些 Rust 代码)
感谢@VTT,这个问题的发生是因为不同平台上的jpg
解释不同。切换到png
解决问题
我正在为基于 Rust 的 OpenCV 编写一个跨平台包装器。我写了几个测试来检查我的包装器是否正常工作。一些测试通过了,一些测试失败了,值略有不同,但一个测试的结果完全不同。
右边的数字是我在 windows 上得到的,左边的是我在 linux
上得到的---- compare_hist_chi_square stdout ----
thread 'compare_hist_chi_square' panicked at '2697.981816285168 == 1360.7', tests/test_imgproc.rs:81:4
---- compare_hist_bhattacharyya stdout ----
thread 'compare_hist_bhattacharyya' panicked at '0.6798259690477988 == 0.6679', tests/test_imgproc.rs:81:4
---- compare_hist_chi_square_alternative stdout ----
thread 'compare_hist_chi_square_alternative' panicked at '41.65613074156445 == 41.027', tests/test_imgproc.rs:81:4
---- compare_hist_correlation stdout ----
thread 'compare_hist_correlation' panicked at '0.20456957916644988 == 0.211', tests/test_imgproc.rs:81:4
---- compare_hist_intersection stdout ----
thread 'compare_hist_intersection' panicked at '5.440850785933435 == 5.682', tests/test_imgproc.rs:81:4
---- compare_hist_kullback_leibler_divergence stdout ----
thread 'compare_hist_kullback_leibler_divergence' panicked at '55.71912075710992 == 54.06287', tests/test_imgproc.rs:81:4
我试图从 this article 重现代码。我拍摄了相同的图像并希望获得相同的结果。然而,这并没有发生。
这里是一些测试的Rust代码(仅供参考):
extern crate cv;
extern crate float_cmp;
mod utils;
use cv::*;
use cv::imgproc::*;
use float_cmp::ApproxEqRatio;
use utils::*;
#[test]
#[should_panic]
fn compare_hist_different_dimensions_panic() {
let first_image = load_unchanged("assets/Histogram_Comparison_Source_0.jpg");
let second_image = load_unchanged("assets/Histogram_Comparison_Source_1.jpg");
let _ = first_image.compare_hist(&second_image, HistogramComparisionMethod::Corellation).unwrap();
}
#[test]
fn compare_hist_correlation() {
compare_hist(HistogramComparisionMethod::Corellation, 0.211);
}
#[test]
fn compare_hist_chi_square() {
compare_hist(HistogramComparisionMethod::ChiSquare, 1360.7);
}
#[test]
fn compare_hist_intersection() {
compare_hist(HistogramComparisionMethod::Intersection, 5.682);
}
#[test]
fn compare_hist_bhattacharyya() {
compare_hist(HistogramComparisionMethod::Bhattacharyya, 0.6679);
}
#[test]
fn compare_hist_chi_square_alternative() {
compare_hist(HistogramComparisionMethod::ChiSquareAlternative, 41.027);
}
#[test]
fn compare_hist_kullback_leibler_divergence() {
compare_hist(
HistogramComparisionMethod::KullbackLeiblerDivergence,
54.06287,
);
}
fn compare_hist(method: HistogramComparisionMethod, expected_result: f64) {
let first_image = get_image_histogram("assets/Histogram_Comparison_Source_0.jpg");
let second_image = get_image_histogram("assets/Histogram_Comparison_Source_1.jpg");
let result = first_image.compare_hist(&second_image, method).unwrap();
assert_eq(result, expected_result);
}
fn get_image_histogram(path: &'static str) -> Mat {
let image = load_unchanged(path);
let image = image.cvt_color(ColorConversionCodes::BGR2HSV);
let hsize = [50, 60];
let h_ranges = [0_f32, 180_f32];
let s_ranges = [0_f32, 256_f32];
let ranges = [
h_ranges.as_ptr() as *const f32,
s_ranges.as_ptr() as *const f32,
];
let channels = [0, 1];
let image = image.calc_hist(
channels.as_ptr(),
Mat::new(),
2,
hsize.as_ptr(),
ranges.as_ptr(),
);
let image = image.normalize(0_f64, 1_f64, NormTypes::NormMinMax);
image
}
fn assert_eq(a: f64, b: f64) {
assert!(a.approx_eq_ratio(&b, 0.001), format!("{} == {}", a, b));
}
pub fn load_unchanged<P: AsRef<Path>>(img: P) -> Mat {
let buf = load_image_as_buf(img);
Mat::imdecode(&buf, ImreadModes::ImreadUnchanged)
}
fn load_image_as_buf<P: AsRef<Path>>(img: P) -> Vec<u8> {
let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
d.push(img);
let mut buf = Vec::new();
File::open(d).unwrap().read_to_end(&mut buf).unwrap();
buf
}
可能是因为 jpg
和不同平台的 jpg
读者不同,但它不能解释 2697.98
vs 1360.7
,几乎是 2 倍的差异!
这里可能出了什么问题? Here is my entire pull request 我正在尝试添加此功能的地方(小心,其中包含一些 Rust 代码)
感谢@VTT,这个问题的发生是因为不同平台上的jpg
解释不同。切换到png
解决问题