在 OpenCV 中使用我自己的公式将 RGB 转换为灰色

Posted

技术标签:

【中文标题】在 OpenCV 中使用我自己的公式将 RGB 转换为灰色【英文标题】:Convert RGB to Gray with my own formula in OpenCV 【发布时间】:2015-07-13 10:24:41 【问题描述】:

我想像这个函数一样将 RGB 图像转换为灰色:

Imgproc.cvtColor(mRgba, mGrey, Imgproc.COLOR_RGBA2GRAY);

但是 openCV 使用一个特定的公式(0.299*R + 0.587*G + 0.114*B 我认为?),我想使用 min(R,G,B) 代替。

有没有一种高效的方法来做到这一点? (这是适用于 android 的 OpenCV,因此适用于 Java)

编辑:

这是我应该早点完成的分析:

捕获相机的基本应用程序以 12 FPS 运行

使用 OpenCV 的 cvtColor():12 FPS(速度差异微不足道) Mark Miller 的回答是:1.5 FPS Mark Miller 的回答和 Miki 的优化(获取数据指针一次):7 FPS

这可能看起来令人难以置信,但只是这个小功能花费了 FPS 的一半。该设备还可以以不错的速度(3-4 FPS)运行非常复杂的东西,例如 ORB,并且所有 O(n) C++ 例程都没有 FPS 差异。也只是 Miki 的“技巧”使函数快了 10 倍。

【问题讨论】:

你需要从RGB转灰度??? 是的,但我还想要一种方法来告诉 openCV 转换时必须使用的公式 为此,您是否将 openCV 库导入到您的项目中? “有没有一种高效的方法来做到这一点?” - 不,你不能用 java 来做,即使使用 jni 也会很辛苦。 @Parth Bhayani 不,我的整个项目都是基于 openCV。 (我在标题中添加了“openCV”,对不起) 【参考方案1】:

没有预先构建的方法可以为 OpenCV 提供任意函数以转换为灰度。剩下的选项是使用 RGB 通道本身。

for (int x = 0; x < mRgba.cols(); x++)

    for (int y = 0; y < mRgba.rows(); y++)
    
        double[] rgb = mRgba.get(x, y);
        mGray.put(x, y, Math.min(rgb[0], Math.min(rgb[1], rgb[2])));
    

正如您所提到的,它可能太慢了,尤其是对于大图像和来自 if 语句的分支。但是,优化的三个规则:(1)不要做,(2)暂时不要做,(3)Profile first。简而言之,首先尝试易于编码的版本,然后一旦你知道这部分是慢速部分[即通过运行它并计时],更改代码以提高效率。

【讨论】:

你得到了我的 -1 的代码,但 +1 的优化考虑。所以 0 :D @Miki 代码有什么问题?它是用Java编写的,而且速度很慢?欢迎编辑和 cmets。 好吧,至少反转内循环和外循环(这样你就可以在ram中顺序访问数据并优化缓存),我不太了解Java的做事方式,但如果它是在C++中的话,我会获取每一行的指针并处理指针。我不知道这样做的 java 方式(这就是我没有发布答案的原因)。从我对问题的评论中可以看出,我非常同意您对优化的看法。 啊,这应该可以获取指向数据的指针Mat fv; ... ; int size = (int) fv.total() * fv.channels(); double[] buff = new double[size]; fv.get(0, 0, buff); @Miki 这个“技巧”太棒了,使函数至少快 10 倍。最后我没有使用 min ,因为它仍然太慢了,但是在我的代码的其他部分应用这个技巧让它们快了很多

以上是关于在 OpenCV 中使用我自己的公式将 RGB 转换为灰色的主要内容,如果未能解决你的问题,请参考以下文章

rgb转化到hsv图像外观会变吗opencv

PHP HSV转RGB公式理解

FPGA_verilog_RGB转YUV代码分享

S0.2 灰度图

YUV420转RGB

opencv python将图像读取为RGB