2

我正在尝试模拟从标记中脱颖而出的图像。到目前为止,这是我的代码,它完成了图片中的操作。本质上,我只是想旋转图像以使其与棋盘正交。

如您所见,我使用代码来查找归一化方形图像和相应棋盘角之间的转换矩阵。然后我用warpPerspective得到你看到的图像。我知道我可以使用来自的旋转向量solvePnP来获得一个旋转矩阵,rodrigues()但我不知道下一步是什么

在此处输入图像描述

def transformTheSurface(inputFrame):
    ret, frameLeft = capleft.read()
    capGray = cv2.cvtColor(frameLeft,cv2.COLOR_BGR2GRAY)
    found, corners = cv2.findChessboardCorners(capGray, (5,4), None, cv2.CALIB_CB_NORMALIZE_IMAGE + cv2.CALIB_CB_ADAPTIVE_THRESH ) #,None,cv2.CALIB_CB_FAST_CHECK)
    if (found):
        npGameFrame = pygame.surfarray.array3d(inputFrame)
        inputFrameGray = cv2.cvtColor(npGameFrame,cv2.COLOR_BGR2GRAY)
        cv2.drawChessboardCorners(frameLeft, (5,4), corners, found)
        q = corners[[0, 4, 15, 19]]
        ret, rvecs, tvecs = cv2.solvePnP(objp, corners, mtx, dist)
        ptMatrix = cv2.getPerspectiveTransform( muffinCoords, q)

        npGameFrame = cv2.flip(npGameFrame, 0)

        ptMatrixWithXRot = ptMatrix * rodRotMat[0]
        #inputFrameConv = cv2.cvtColor(npGameFrame,cv2.COLOR_BGRA2GRAY)
        transMuffin = cv2.warpPerspective(npGameFrame, ptMatrix, (640, 480)) #, muffinImg, cv2.INTER_NEAREST, cv2.BORDER_CONSTANT,  0)

编辑:

我添加了更多代码,希望创建自己的 3x3 转换矩阵。我使用了以下参考。这是我的代码:

#initialization happens earlier in code
muffinCoords = np.zeros((4,2), np.float32)
muffinCoords[0] = (0,0)
muffinCoords[1] = (200,0)
muffinCoords[2] = (0,200)
muffinCoords[3] = (200,200)

A1 = np.zeros((4,3), np.float32)
A1[0] = (1,0,322)
A1[1] = (0,1,203)
A1[2] = (0,0,0)
A1[3] = (0,0,1)

R = np.zeros((4,4), np.float32)
R[3,3] = 1.0

T = np.zeros((4,4), np.float32)
T[0] = (1,0,0,0)
T[1] = (0,1,0,0)
T[2] = (0,0,1,0)
T[3] = (0,0,0,1)
#end initialization

#load calib data derived using cv2.calibrateCamera, my Fx and Fy are about 800
loadedCalibFileMTX = np.load('calibDataMTX.npy')
mtx = np.zeros((3,4), np.float32)
mtx[:3,:3] = loadedCalibFileMTX

相机校准输出

#this is new to my code, creating what I interpret as Rx*Ry*Rz
ret, rvecCalc, tvecs = cv2.solvePnP(objp, corners, loadedCalibFileMTX, dist)
rodRotMat = cv2.Rodrigues(rvecCalc)
R[:3,:3] = rodRotMat[0]

R的输出

#then I create T
T[0,3] = tvecs[0]
T[1,3] = tvecs[1]
T[2,3] = tvecs[2]

T的输出

# CREATING CUSTOM TRANSFORM MATRIX
# A1 -> 2d to 3d projection matrix
# R-> rotation matrix as calculated by solve PnP, or Rx * Ry * Rz
# T -> converted translation matrix, reference from site, vectors pulled from tvecs of solvPnP
# mtx -> 3d to 2d matrix
# customTransformMat = mtx * (T * (R * A1)) {this is intended calculation of following}
first = np.dot(R, A1)
second = np.dot(T, first)
finalCalc = np.dot(mtx, second)

finalCalc 的输出,后跟注释中的公式

finalNorm = finalCalc/(finalCalc[2,2]) # to make sure that the [2,2] element is 1

finalNorm 的输出

transMuffin = cv2.warpPerspective(npGameFrame, finalNorm, (640, 480), None, cv2.INTER_NEAREST, cv2.BORDER_CONSTANT,  0)
#transMuffin is returned as undefined here, any help?

# using the cv2.getPerspectiveTransform method to find what you can find pictured at the top
ptMatrix = cv2.getPerspectiveTransform( muffinCoords, q)

ptMatrix 的输出

4

1 回答 1

0

我终于找到了正确的方法。你可以在这里找到代码https://github.com/mikezucc/augmented-reality-fighter-pygame

注意:

几乎所有的游戏代码都是由 Leif Theiden 编写的,并且在 .py 文件中指定了许可证。与计算机视觉相关的代码在 states.py 中。我用这个游戏只是为了展示它可以为其他希望开始使用简单计算机视觉的人完成。

我的代码每次调用一个新的表面(PyGame for frame)以显示在主窗口上时都会打开一个线程。我在此时启动一个线程并执行一个简单的计算机视觉函数,该函数执行以下操作:

  1. 在相机流帧中搜索 5x4 棋盘 (cv2.findChessboardCorners)
  2. 然后将找到的角绘制到图像上
  3. 使用 cv2.solvePnP 导出近似位姿(旋转和平移向量)
  4. 然后将描述正方形的 3d 点从步骤 3 确定的 3d 空间投影到 2d 空间中。这用于将预定的 3d 结构转换为可用于在 2d 图像上绘制图形的东西。
  5. 然而,这一步找到了从一组 2d 正方形点(游戏帧的尺寸)到新找到的投影 2d 点(3d 帧)的转换。现在您可以看到我们正在尝试做的只是进行两步转换。
  6. 然后我对捕获的流帧和转换后的游戏帧执行基本教程样式添加以获得最终图像

变量:

+ from3dTransMatrix-> 投影 3d 结构的点到 2d 点。这些是你看到的红点

+ q-> 这是我们确定姿势的参考平面

+ ptMatrix-> 最终的转换,将游戏帧转换为适合投影帧

查看最顶层文件夹中的屏幕;]

请享用!

于 2014-10-23T07:08:51.033 回答