我有以下示例代码来计算红色像素的百分比,

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,但我找不到会导致这种情况的模式)。

最佳答案

看来您正在使用divide函数的this重载:

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



执行操作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结果。在第二种情况下,它是浮点数,因此不进行舍入。

07-26 02:23