我有以下示例代码来计算红色像素的百分比,
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结果。在第二种情况下,它是浮点数,因此不进行舍入。