OpenCV Mat将答案分开错误

时间:2016-10-03 16:48:32

标签: java 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] );

        }

    }
}

运行它我希望结果在()s然而我显然得到奇怪的结果。我一开始认为它与整数除法有关(参见: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 / 1.0和255/255,1.0映射到6.0,但我找不到会导致这种情况的模式)。

1 个答案:

答案 0 :(得分:3)

您似乎正在使用divide函数的this重载:

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

参数:

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

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

NB:请注意第4个参数的实际含义,即传递Core.CV_64FC1

通过一些研究,您可以发现常量CV_64FC1的值为6

这意味着实际上,正在执行的计算是:

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

其余的很简单。

请注意文档中要求输出数组&#34;与src2具有相同大小和类型的要求。&#34; 在第一种情况下,当两个输入数组为{ {1}},第二个条件不满足,因此分配了一个新数组。

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