【问题标题】:Reading jpg file in OpenCV vs C# Bitmap在 OpenCV vs C# Bitmap 中读取 jpg 文件
【发布时间】:2015-12-10 14:29:25
【问题描述】:

经过多次实验,我发现在 C++ (OpenCV) 中读取彩色 jpg 文件:

auto temp(cv::imread("xxx.jpg");

不同于使用 C# 位图读取同一个文件:

var temp=new bitmap("xxx.jpg");

结果不同。如果我对它们都应用了一些算法,比如 GoodFeatureToTrack,会有显着差异。

问题是: 如何在 OpenCV 中采用 C# 位图加载方式。因此,如果我直接在本机部分或从 C# Wrapper 加载图像,我会得到相同的结果。

谢谢

编辑:

此代码是一个 c++ 函数,它采用一些结构,其中包含在管理程序 (c#) 中加载的图像,然后在 opencv 中加载相同的图像并比较它们.. 有一个不同的!

    extern "C" _declspec (dllexport) void test_diff(authenticator_reference_structure* referecnces){
    auto image(cv::imread("white.jpg"));

    cv::imshow("opencv", image);
    auto wrpped(referecnces->references->images->image.getMat());

    cv::imshow("C#", wrapped);
    cv::Mat ss;
    cv::absdiff(image, wrapped, ss);

    cv::threshold(ss, ss, 1, 255, CV_THRESH_BINARY);
    cv::imshow("Diff", ss);
    cv::waitKey();

}

【问题讨论】:

  • 什么类型的图片?灰度?颜色?您是否尝试过将不同的标志传递给imread
  • 彩色图像“不同的标志”是为了什么?
  • 您可以使用CV_LOAD_IMAGE_ANYDEPTH 处理16 位或32 位图像,或使用CV_LOAD_IMAGE_GRAYSCALE 转换为灰度。默认值为CV_LOAD_IMAGE_COLOR,这将产生一个 3 通道图像。你的图片可能有 Alpha 通道吗?
  • 我不认为它包含 alpha 通道...但是,我将尝试 CV_LOAD_IMAGE_ANYDEPTH
  • 我试过了。它不返回 3 通道。我需要结果是 3 个通道(颜色)

标签: c# c++ opencv bitmap jpeg


【解决方案1】:

也许您可以使用getImage() 代替getMat()

这里正在解决一个类似的问题(在 C# 而不是 C++ 中使用 openCV)
http://www.emgu.com/forum/viewtopic.php?t=188

【讨论】:

  • 您的意思是在我的 c# 应用程序中包含 EMGU 并使用它的图像加载器?这是可能的解决方案,但我不想仅仅为此目的将 EMGU 添加到我的 c# 应用程序中..
  • Opencv 包含在本机部分中,但它不在托管部分中
  • 您可以单独安装 emgu,包括标题和链接。您(大概)也没有在您的项目中包含 OpenCV?见emgu.com/wiki/index.php/Main_Page#Architecture_Overview——很多东西你称之为它而不是OpenCV(见emgu.com/wiki/index.php/Tutorial
  • 抱歉,仍在编辑中。但是 C## 也将在本机部分(它是 Windows 特定的),因此也不应该更改托管依赖项?
  • 问题解决了吗?您可以通过将质量设置为 100% 的 PNG 制作 jpeg 来进行测试。我认为仍然可以进行 DCT,但不会丢弃任何系数。除了 jpeg 解码会产生像您的 Diffpicture 中的伪像。
【解决方案2】:

正如其他人指出的那样,如果您想在 OpenCV 中读取未修改的图像,请将 C++ function 中的标志设置为 -1,如下所示:

cv::Mat img = cv::imread("xxx.jpg", -1);

或者使用定义的enum值:

cv::Mat img = cv::imread("xxx.jpg", cv::IMREAD_UNCHANGED);

另请注意,JPEG 图像不保证被不同解码器解码的位完全相同!最好使用像 PNG 这样的无损格式(请参阅#4148#4046、...)。

【讨论】:

  • @HumamHelfawi:请参阅我关于有损 JPEG 解码的说明
  • 是的,我做到了.. 但是更改整个编码不是一种选择,甚至我在当前项目中也无权这样做
  • 我的意思是,当你想比较算法的不同实现时,在测试中使用 PNG 图像(无损,把它们想象成 ZIP 文件)
  • 如果我理解正确,您已经在 C# 中开发了您的算法(某种特征检测),并且您想将其与 C++ 实现进行比较。我的意思是您应该使用 PNG 而不是 JPEG 图像仅用于比较,以排除在您发现两种实现之间存在差异的情况下的可能性。显然,转换 1M 组图像毫无意义,这些图像已经以有损格式存储和压缩,我只是在谈论测试阶段。
  • @HumamHelfawi:啊哈,这就是我最初怀疑的 :) 不同的库对 JPEG 图像的解码会略有不同。你对此无能为力。如果您想要位精确性,则必须考虑其他编解码器。此外,如果您开发的算法在您向其提供具有这些差异的图像时会给出截然不同的结果,那么 IMO 这是一个问题。您应该稍微放松一下参数(例如平滑输入图像,或者使用稍微大一点的图像)进行图像过滤时的窗口大小,诸如此类的事情...)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-21
  • 1970-01-01
  • 2012-03-20
  • 2016-08-19
  • 2010-10-31
  • 2018-12-12
  • 1970-01-01
相关资源
最近更新 更多