OpenCV:如何在cv2.fisheye.undistortImage之后得到一个点的位置?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV:如何在cv2.fisheye.undistortImage之后得到一个点的位置?相关的知识,希望对你有一定的参考价值。

我想创造一个鱼眼效果,但我不熟悉cv2.fisheye.undistortImage()cv2.fisheye.undistortPoints()。这是我的代码:

import cv2
import glob
import numpy as np

# grab a list of jpg from one folder
img_list = glob.glob('/home/folder/*.jpg')

# get the K and D for cv2.fisheye.undistortImage
K = np.array([[900.,0,512],
        [0,900.,288],
        [0.,0.,1]])

D = np.array([4.,100.,0.,0.])

# create a random point
point = np.array([[[300.,300.],[300,400],[400,400],[400,300]]])

# get a knew for cv2.fisheye.undistortImage
Knew = K.copy()
Knew[(0,1),(0,1)] = Knew[(0,1),(0,1)]


for img_path in img_list:

        img = cv2.imread(img_path)

        # draw all four points on the original image
        cv2.circle(img,(300,300), 5, (0,0,255), -1)
        cv2.circle(img,(400,300), 5, (0,0,255), -1)
        cv2.circle(img,(300,400), 5, (0,0,255), -1)
        cv2.circle(img,(400,400), 5, (0,0,255), -1)

        # distort the images
        img_out = cv2.fisheye.undistortImage(img,K,D=D,Knew=Knew)
        # send the points to cv2.fisheye.undistortPoints
        point_out = cv2.fisheye.undistortPoints(point,K =K1, D=D)

        # looks like the out is around (-1,1) so i tried to recover back
        #cv2.circle(img,(600,300), 5, (0,0,255), -1)
        x = int((512.+(point_out[0][0][0]*1024)))
        y = int((288.+(point_out[0][0][1]*576)))
        cv2.circle(img_out,(x,y), 5, (0,255,0), 1)
        x = int((512.+(point_out[0][1][0]*1024)))
        y = int((288.+(point_out[0][1][1]*576)))
        cv2.circle(img_out,(x,y), 5, (0,255,0), 1)
        x = int((512.+(point_out[0][2][0]*1024)))
        y = int((288.+(point_out[0][2][1]*576)))
        cv2.circle(img_out,(x,y), 5, (0,255,0), 1)
        x = int((512.+(point_out[0][3][0]*1024)))
        y = int((288.+(point_out[0][3][1]*576)))
        cv2.circle(img_out,(x,y), 5, (0,255,0), 1)

        # save the img
        cv2.imwrite(img_path+'.jpg',img_out,[100])

enter image description here

此代码是一个尝试在执行undistortImage()后获取输出位置的实验。首先,我在原始图像上绘制一个红点,例如(300,300)。然后,我使用undistortImage()进行鱼眼效果,因此红点可能位于不同的位置。但是,我不知道如何计算正确的位置。

我认为undistortPoints()可能会得到正确的位置。不幸的是,绿色圆圈显示我的方法是错误的。有人可以告诉我们如何获得正确的价值吗?

答案

在调用fisheye.undistortImage时,使用Knew为失真图像指定摄像机矩阵。当你打电话给fisheye.undistortPoints时,你需要做同样的事情。如果您阅读文档,您将看到您可以给出一个P参数,即“新相机矩阵(3x3)或新投影矩阵(3x4)”。那正是你想要的。

for img_path in img_list:

    img = cv2.imread(img_path)

    # draw all four points on the original image
    cv2.circle(img,(300,300), 5, (0,0,255), -1)
    cv2.circle(img,(400,300), 5, (0,0,255), -1)
    cv2.circle(img,(300,400), 5, (0,0,255), -1)
    cv2.circle(img,(400,400), 5, (0,0,255), -1)

    # distort the images
    img_out = cv2.fisheye.undistortImage(img,K,D=D,Knew=Knew)
    # send the points to cv2.fisheye.undistortPoints
    point_out = cv2.fisheye.undistortPoints(point,K =K, D=D, P=Knew)[0]
    for point in point_out:
        cv2.circle(img_out, (int(point[0]), int(point[1])), 5, (0,255,0), 1)

    # save the img
    cv2.imwrite(img_path+'.jpg',img_out,[100])

以上是关于OpenCV:如何在cv2.fisheye.undistortImage之后得到一个点的位置?的主要内容,如果未能解决你的问题,请参考以下文章

Qt-OpenCV:如何在 Qt 中显示灰度图像(opencv)

在哪里/如何在 OpenCV 中放置构建文件

android如何在 java opencv 中查找最大轮廓

opencv安装在TX2上如何卸载并安装opencv

如何在vs2010上安装opencv

如何在Eclipse下配置opencv