Java 灰度滞后的RGB算法

Java 灰度滞后的RGB算法,java,opencv,optimization,colors,lag,Java,Opencv,Optimization,Colors,Lag,尝试实现将图片从RGB转换为灰色的转换方法。 当我使用我的方法并在ImageView中显示渲染时,它的滞后性非常大,当我使用OpenCV库中的cvtColor函数时,它的效果非常好。 谁能解释一下问题出在哪里? 以下是我的方法: public void RGBToGray(Mat m){ for(int i = 0; i < m.rows(); i++){ for(int j = 0; j < m.cols(); j++){ doubl

尝试实现将图片从RGB转换为灰色的转换方法。 当我使用我的方法并在ImageView中显示渲染时,它的滞后性非常大,当我使用OpenCV库中的cvtColor函数时,它的效果非常好。 谁能解释一下问题出在哪里? 以下是我的方法:

public void RGBToGray(Mat m){
    for(int i = 0; i < m.rows(); i++){
        for(int j = 0; j < m.cols(); j++){
            double[] pix = m.get(i, j);
            pix[0] = pix[1] = pix[2] = (0.21)*pix[0]+(0.72)*pix[1]+(0.07)*pix[2];
            m.put(i, j, pix);
        }
    }
}
public void RGBToGray(材料m){
对于(int i=0;i根据Dan Masek的评论,这里有一个解决方案,供那些将看到这篇文章的人使用:

public static void RGBToGray2(Mat m){
    ArrayList<Mat> sousMatrices = new ArrayList<Mat>();
    Core.split(m, sousMatrices);
    Mat result = new Mat();
    Core.addWeighted(sousMatrices.get(0), 0.21, sousMatrices.get(1), 0.72, 0, result);
    Core.addWeighted(sousMatrices.get(2), 0.07, result, 1 ,0 , result);
    sousMatrices.set(0,result);
    sousMatrices.set(1,result);
    sousMatrices.set(2,result);
    Core.merge(sousMatrices, m);
}
公共静态空隙RGBToGray2(材料m){
ArrayList sousMatrices=新的ArrayList();
核心分裂(m,sousMatrices);
Mat结果=新Mat();
增加权重(sousMatrices.get(0),0.21,sousMatrices.get(1),0.72,0,result);
Core.addWeighted(sousMatrices.get(2),0.07,result,1,0,result);
sousMatrices.set(0,结果);
sousMatrices.set(1,结果);
sousMatrices.set(2,结果);
核心合并(sousMatrices,m);
}

您缺少OpenCV中
cvtColor
实现的并行化和矢量化。最重要的是,每个迭代有两个函数调用——IIRC这将涉及JNI,因此会有一些相关的开销(如果不是每个图像有两个调用,而是每个像素有两个调用,则会更加明显)。对
m.get
m.put
的调用将消耗大量时间。请注意(国际电信联盟)根据我的经验,将方程定义为
Grey=0.299Red+0.587Green+0.114Blue
,这非常有效。实际上,考虑到您使用的是
Mat
,没有什么理由这样循环。OpenCV提供了将
Mat
拆分为单个通道,以及将它们添加在一起,并将通道合并回多个c的方法channel
Mat
。好吧,避免m.get和m.put会解决这个问题,但是如果没有这些函数,我该如何实现算法呢?我的意思是,将一个Mat分成两个矩阵,应用一个比例,然后合并它们,这些操作是如何工作的?不是通过for循环来修改每个像素吗?类似于,3倍于一个通道“灰色”
Mat
。如果需要结果为3个通道,则任何一个
合并
(将相同的“灰色”
Mat
三次插入输入
列表
),
mixChannels
cvtColor
将完成此任务。其他选项是使用
get
一次获取所有像素的数组并执行循环。