opencv undistortPoints 不会不失真

问题描述

我有一个带鱼眼镜头的相机。我成功地取消了我的图像失真,但我想取消了点坐标的失真。我知道地图包含 dst 中每个像素的 src 图像坐标,所以我不能直接使用没有一些迭代算法的那些。我认为 undistortPoints() 会这样做,但它错误地转换了第一点并且不会改变第二点。使用 undistortPointsIter() 并将标准设置得更高也不起作用。

之前有人问过类似的问题,this answer 对我也不起作用。我使用 undistortPoints() 得到完全相同的结果。

那么如何从失真图像的像素点中获取未失真图像的像素点?

我的相机参数:

print(K)
print(D)
print(Dims)

[[338.37324094   0.         319.5       ]
 [  0.         339.059099   239.5       ]
 [  0.           0.           1.        ]]
[[ 0.01794191]
 [-0.12190366]
 [ 0.14111533]
 [-0.09602948]]
(640,480)

我的代码

img = cv2.imread('Chessboards\img_021.jpg')
img_undistorted = cv2.remap(img,unfishmap1,unfishmap2,interpolation=cv2.INTER_LINEAR,borderMode=cv2.BORDER_CONSTANT) 

points1=[]
points1.append((165,260))
points1.append((175,410))

print(points1)

img2= img.copy()
for p in points1:
    cv2.circle(img2,p,6,(0,255),2)
imgshow(img2)

point_matrix = np.zeros(shape=(len(points1),1,2),dtype=np.float32)

for i in range(0,len(points1)):
    point_matrix[i][0][0] = points1[i][0]
    point_matrix[i][0][1] = points1[i][1]
    
print(point_matrix)
    
points_undistorted = cv2.undistortPoints(point_matrix,K,D,R=None,P=K)
points2=[]
for p in points_undistorted:
    points2.append( (int(p[0][0]),int(p[0][1])) )
  
print(points2)

img2= img_undistorted.copy()
for p in points2:
    cv2.circle(img2,2)
imgshow(img2)

#expected
points3=[]
points3.append((155,265))
points3.append((150,443))

print(points3)

img2= img_undistorted.copy()
for p in points3:
    cv2.circle(img2,2)
imgshow(img2)

结果:

distorted

undistorted with undistortPoints

undistorted with expected points

解决方法

感谢 micka 提供的解决方案。

这对我有用:

source image

import matplotlib.pyplot as plt
plt.rcParams['figure.dpi'] = 150
import cv2
import copy
import os
import numpy as np

def imgshow(img):
    if len(img.shape) == 3:
        plt.imshow(img[:,:,::-1])
    else:
        plt.imshow(img,cmap='gray',vmin=0,vmax=255)
    plt.show() 


K = np.array( [[338.37324094,319.5],[0,339.059099,239.5],1]],dtype=np.float64)
D = np.array( [[ 0.01794191],[-0.12190366],[ 0.14111533],[-0.09602948]],dtype=np.float64)
new_size = (640,480)

Knew = K.copy()
# alpha = 0.6
# Knew,roi = cv2.getOptimalNewCameraMatrix(K,D,new_size,alpha,centerPrincipalPoint = True)
    
unfishmap1,unfishmap2 = cv2.fisheye.initUndistortRectifyMap(K,np.eye(3),Knew,cv2.CV_32F)
unfishmap1,unfishmap2 = cv2.convertMaps(unfishmap1,unfishmap2,cv2.CV_16SC2)

img = cv2.imread('3FYUT.jpg')
img_undistorted = cv2.remap(img,unfishmap1,interpolation=cv2.INTER_LINEAR,borderMode=cv2.BORDER_CONSTANT) 

points1=[]
points1.append((165,260))
points1.append((175,410))

print(points1)

img2= img.copy()
for p in points1:
    cv2.circle(img2,p,6,(0,255),2)
imgshow(img2)

point_matrix = np.zeros(shape=(len(points1),1,2),dtype=np.float32)

for i in range(0,len(points1)):
    point_matrix[i][0][0] = points1[i][0]
    point_matrix[i][0][1] = points1[i][1]
        
points_undistorted = cv2.fisheye.undistortPoints(point_matrix,K,P=Knew)

points2=[]
for p in points_undistorted:
    points2.append( (int(p[0][0]),int(p[0][1])) )

print("fisheye.undistortPoints:")    
print(points2)

img2= img_undistorted.copy()
for p in points2:
    cv2.circle(img2,2)
imgshow(img2)

print("expected:")
points3=[]
points3.append((155,265))
points3.append((150,443))

print(points3)

img2= img_undistorted.copy()
for p in points3:
    cv2.circle(img2,2)
imgshow(img2)

结果:

fisheye.undistortPoints:
[(152,261),(147,441)]
expected:
[(155,265),(150,443)]

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...