2016-10-03 57 views
0

我有以下示例代码,计算红色像素的百分比,OpenCV的垫鸿沟错答案

import org.opencv.core.*; 


public class ImageProcessing { 
    static 
    { 
     System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 
    } 

    public static void main(String[] args) 
    { 
     Mat red = Mat.zeros(5, 1, CvType.CV_8UC1); 
     Mat sum = Mat.zeros(5, 1, CvType.CV_8UC1); // sum of red, green, and blue 

     double[] red_data = {1, 1, 1, 1,255}; 
     double[] sum_data = {1,11,12,13,255}; 
     red.put(0, 0, red_data); 

     sum.put(0, 0, sum_data); 

     Mat percentage = Mat.zeros(5, 1, CvType.CV_64FC1); 

     //red.convertTo(red, CvType.CV_64F); 
     //sum.convertTo(sum, CvType.CV_64F); 
     Core.divide(red, sum, percentage, CvType.CV_64FC1); 



     System.out.println("Results"); 
     for (int i = 0; i < 5; i++) 
     { 
      System.out.printf("%d: %10f/%10f = %10f (%10f) \n", i+1, red.get(i, 0)[0], 
        sum.get(i, 0)[0], 
        percentage.get(i, 0)[0], 
        red.get(i, 0)[0]/sum.get(i, 0)[0]); 

     } 

    } 
} 

运行它,我期待的结果()■但我显然得到了奇怪的结果。起初我认为它与整数除法有关(请参阅:divide two matrices in opencv)。但是将它们转换为64位浮点数(注释掉的行数)。只会给出其他奇怪的结果。

没有浮充转换

Results 
1: 1.000000/ 1.000000 = 6.000000 ( 1.000000) 
2: 1.000000/11.000000 = 1.000000 ( 0.090909) 
3: 1.000000/12.000000 = 0.000000 ( 0.083333) 
4: 1.000000/13.000000 = 0.000000 ( 0.076923) 
5: 255.000000/255.000000 = 6.000000 ( 1.000000) 

Process finished with exit code 0 

随着转换到64位漂浮

Results 
1: 1.000000/ 1.000000 = 6.000000 ( 1.000000) 
2: 1.000000/11.000000 = 0.545455 ( 0.090909) 
3: 1.000000/12.000000 = 0.500000 ( 0.083333) 
4: 1.000000/13.000000 = 0.461538 ( 0.076923) 
5: 255.000000/255.000000 = 6.000000 ( 1.000000) 

我注意到有一致的结果,其中有一个明显的映射(1.0映射到6.0两者1.0/1.0和255/255,但我找不到会导致这种情况的模式)。

回答

3

看来,您正在使用this超载divide功能:

public static void divide(Mat src1, Mat src2, Mat dst, double scale) 

参数:

  • SRC 1 - 第一源阵列。
  • src2 - 与src1具有相同大小和类型的第二个源数组。
  • dst - 与src2具有相同大小和类型的目标数组。
  • 比例 - 标量因子。

执行操作dst(I) = saturate(src1(I) * scale/src2(I))

注意:请注意第4个参数的实际含义,您在那里通过Core.CV_64FC1

通过一点研究,你可以发现常数CV_64FC1的值是6

这意味着,在现实中,正在执行的计算是:

1 * 6/1 
1 * 6/11 
1 * 6/12 
1 * 6/13 
255 * 6/255 

其余部分很简单。

请注意文档中输出数组应为“与src2具有相同大小和类型的要求”。在第一种情况下,当两个输入数组为CV_8UC1时,第二个条件不符合,因此分配了一个新数组。

由于在第一种情况下输出是整数数组,因此您会看到rounded结果。在第二种情况下,它是浮点数,所以没有舍入。

+1

就是这样,看着我误认为除法的分割函数的代码(double scale,Mat src2,Mat dst,int dtype),并且错过了第一个参数是一个double而不是另一个Mat。我确实看到所有的结果都是1/6。谢谢。 更改为core.divide(红色,总和,百分比,1,CvType.CV_64FC1);修复 – Zimm3r