【问题标题】:OpenCV Mat divide answers wrongOpenCV Mat 除法答案错误
【发布时间】:2016-10-03 16:48:31
【问题描述】:

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

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

【问题讨论】:

    标签: java opencv


    【解决方案1】:

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

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

    参数:

    • src1 - 第一个源数组。
    • 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 结果。在第二种情况下,它是浮点数,因此不进行舍入。

    【讨论】:

    • 就是这样,查看代码时,我将除法函数误认为是除法(双刻度,Mat src2,Mat dst,int dtype)并且错过了第一个参数是双精度而不是另一个 Mat。我确实看到所有结果都偏离了 1/6。谢谢。更改为 core.divide(red, sum, percent, 1, CvType.CV_64FC1);修好了
    猜你喜欢
    • 1970-01-01
    • 2020-02-12
    • 1970-01-01
    • 1970-01-01
    • 2015-08-09
    • 2019-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多