我现在正在努力完成特定的计算机视觉任务。想象一下,我们有一个道路相机框架。现在我想生成一个新的框架,假想的相机水平翻译。此外,还增加了一个微小的摄像机角度。为了说明这一点,我上传了一个演示图片:
如何在python中创建原始框架中的新框架? 对于我的其他计算机视觉任务,我已经在使用OpenCV了。
答案 0 :(得分:1)
如果您要翻译,请更改图像的平面,这可以使用Homography矩阵来完成。检查透视变换。 Here .
您需要使用矩阵的值H(0,2)和H(2,0)来沿X平移,然后将图像更改为角度,就像在图像中一样。
首先找到具有相同图像的Homography矩阵,然后更改矩阵的上述位置值并将其扭曲。你会得到你想要的。
编辑:Homography只是一个3x3矩阵。每个矩阵元素对应于图像上的特定操作。
Like 0x0位置的元素水平拉伸图像。 1x0位置的元素偏离图像。就像保持左边缘静止并拉下右边缘一样。同样明智的是,其他元素也会进行各自的操作。
现在在单应矩阵中,2x0和0x2的元素被分配用于您想要的任务。即,移动平面并沿X方向移动。通过更改(播放)这些值,您可以获得不同的透视图图像。因此,这也称为透视变换。
答案 1 :(得分:0)
如果具有单应性矩阵,则可以使用OpenCV的warpPerspective函数获取新框架。由于您拥有精确的平移和旋转值,因此您可以根据相机的固有参数自己导出矩阵。
我们知道对于2D图像投影在空间中的3D点,单应性矩阵为
H = K [R | T]
要将点从一个2D图像转换到另一个2D图像,您只需要先将这些点反向投影到3D,然后将它们重新投影到新的图像平面即可。
x’= K [R2 | T2] * [R1 | T1](inv)* K(inv)* x
现在,我知道[R | T]矩阵是3x4,我不确定如何找到它们的逆,但是我发现在this post中共享的一些代码都使用4x4矩阵并将[R2 | T2] * [R1 | T1](inv)合并为一个变换矩阵,并给出从一个摄像机到另一个摄像机的相对旋转和平移,这就是您知道的x和alpha值。我不完全了解3D-> 2D本征矩阵是如何派生的,但是该代码似乎有效,除了它不允许X和Y转换。我已经按原样添加了它们。
import cv2
import numpy as np
rotXdeg = 90
rotYdeg = 90
rotZdeg = 90
f = 600
distX = 500
distY = 500
distZ = 500
def onRotXChange(val):
global rotXdeg
rotXdeg = val
def onRotYChange(val):
global rotYdeg
rotYdeg = val
def onRotZChange(val):
global rotZdeg
rotZdeg = val
def onFchange(val):
global f
f=val
def onDistXChange(val):
global distX
distX=val
def onDistYChange(val):
global distY
distY=val
def onDistZChange(val):
global distZ
distZ=val
if __name__ == '__main__':
#Read input image, and create output image
src = cv2.imread('bef.png')
dst = np.zeros_like(src)
#Create user interface with trackbars that will allow to modify the parameters of the transformation
wndname1 = "Source:"
wndname2 = "WarpPerspective: "
cv2.namedWindow(wndname1, 1)
cv2.namedWindow(wndname2, 1)
cv2.createTrackbar("Rotation X", wndname2, rotXdeg, 180, onRotXChange)
cv2.createTrackbar("Rotation Y", wndname2, rotYdeg, 180, onRotYChange)
cv2.createTrackbar("Rotation Z", wndname2, rotZdeg, 180, onRotZChange)
cv2.createTrackbar("f", wndname2, f, 2000, onFchange)
cv2.createTrackbar("Distance X", wndname2, distX, 1000, onDistXChange)
cv2.createTrackbar("Distance Y", wndname2, distY, 1000, onDistYChange)
cv2.createTrackbar("Distance Z", wndname2, distZ, 1000, onDistZChange)
#Show original image
cv2.imshow(wndname1, src)
h , w = src.shape[:2]
while True:
rotX = (rotXdeg - 90)*np.pi/180
rotY = (rotYdeg - 90)*np.pi/180
rotZ = (rotZdeg - 90)*np.pi/180
#Projection 2D -> 3D matrix
A1= np.matrix([[1, 0, -w/2],
[0, 1, -h/2],
[0, 0, 0 ],
[0, 0, 1 ]])
# Rotation matrices around the X,Y,Z axis
RX = np.matrix([[1, 0, 0, 0],
[0,np.cos(rotX),-np.sin(rotX), 0],
[0,np.sin(rotX),np.cos(rotX) , 0],
[0, 0, 0, 1]])
RY = np.matrix([[ np.cos(rotY), 0, np.sin(rotY), 0],
[ 0, 1, 0, 0],
[ -np.sin(rotY), 0, np.cos(rotY), 0],
[ 0, 0, 0, 1]])
RZ = np.matrix([[ np.cos(rotZ), -np.sin(rotZ), 0, 0],
[ np.sin(rotZ), np.cos(rotZ), 0, 0],
[ 0, 0, 1, 0],
[ 0, 0, 0, 1]])
#Composed rotation matrix with (RX,RY,RZ)
R = RX * RY * RZ
#Translation matrix on the Z axis change dist will change the height
T = np.matrix([[1,0,0,(distX-500)],
[0,1,0,(distY-500)],
[0,0,1,f+(distZ-500)],
[0,0,0,1]])
#Camera Intrinsic matrix 3D -> 2D
A2= np.matrix([[f, 0, w/2,0],
[0, f, h/2,0],
[0, 0, 1,0]])
# Final and overall transformation matrix
H = A2 * (T * (R * A1))
# Apply matrix transformation
cv2.warpPerspective(src, H, (w, h), dst, cv2.INTER_CUBIC)
#Show the image
cv2.imshow(wndname2, dst)
cv2.waitKey(1)