Android OpenCV undistort图像从看似相同的python实现产生不同的结果

时间:2018-01-31 01:56:27

标签: android python opencv opencv4android

我们有一个简单的python例程,它通过调用cv2.fisheye.undistortImage()来获取图像并对其进行解析。它根据输入图像和提供的摄像机矩阵产生预期的结果。

我将python函数移植到Android。当输入相同的输入图像时,Android版本不会产生相同的结果,我不知道为什么。我错过了港口的东西吗?

Python源代码(按预期工作)

cx = 960 
cy = 540
val = 600   

K = np.array([[  val,     0.  ,  cx],
            [    0. ,   val   ,  cy],
            [    0. ,    0.   ,  1.  ]])

# zero distortion coefficients work well for this image
D = np.array([0., 0., 0., 0.])

# use Knew to scale the output
Knew = K.copy()
Knew[(0,1), (0,1)] = 0.4 * Knew[(0,1), (0,1)]

img = cv2.imread('fisheye_sample.jpg')

img_undistorted = cv2.fisheye.undistortImage(img, K, D=D, Knew=Knew)
cv2.imwrite('fisheye_sample_undistorted.jpg', img_undistorted)

现在,移植到Android的python代码如下:

Android端口(未产生预期结果)

float fishVal = 600.0f;
float cX = 960;
float cY = 540;
Mat K = new Mat(3, 3, CvType.CV_32FC1);
K.put(0, 0, new float[]{fishVal, 0, cX});
K.put(1, 0, new float[]{0, fishVal, cY});
K.put(2, 0, new float[]{0, 0, 1});

Mat D = new Mat(1, 4, CvType.CV_32FC1);
D.put(0, 0, new float[]{0, 0, 0, 0});

Mat Knew = K.clone();
Knew.put(0, 0, new float[]{fishVal * 0.4f, 0.0f, cX});
Knew.put(1, 0, new float[]{0.0f, fishVal * 0.4f, cY});
Knew.put(2, 0, new float[]{0.0f, 0.0f, 1.0f});

Mat dst = new Mat(greyScaleMat.rows(), greyScaleMat.cols(), greyScaleMat.type());
Imgproc.undistort(greyScaleMat, dst, K, D, Knew);

给定一个恒定的输入,我期望两个实现产生相同的输出。这不会发生。 Python版本有一些不成比例,但Android版本似乎忽略了一些输入参数。我的Android端口有什么问题我没看到吗?

输入图片 enter image description here

Python输出图像(正确!) 下面的图像没有像预期的那样失真 enter image description here Android输出图片(不正确!) 当如上所述通过Android功能运行时,没有执行不失真。相反,图像按照Knew矩阵按比例缩小。关于如何解释这种差异的任何想法?

enter image description here

1 个答案:

答案 0 :(得分:1)

经过多次头部刮擦,论坛搜索和源代码调查后,我找到了答案。 事实证明,Imgproc.undistort()的实施 与<{1}} 相同

Java / JNI世界中的等价物是cv2.fisheye.UndistortImage()。调用该函数时,输出与python版本相同。

有必要将OpenCV for Android升级到高于3的版本才能访问此功能。