OpenCV在Windows和Linux上有不同的结果

时间:2018-01-26 20:43:29

标签: c++ linux windows opencv cross-platform

我正在为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代码)

1 个答案:

答案 0 :(得分:0)

感谢@VTT,出现此问题的原因是不同平台上的jpg解释不同。切换到png解决问题