Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Opencv getPerspectiveTransform方法给出了不清楚的结果_Python_Opencv_Perspective_Homography - Fatal编程技术网

Python Opencv getPerspectiveTransform方法给出了不清楚的结果

Python Opencv getPerspectiveTransform方法给出了不清楚的结果,python,opencv,perspective,homography,Python,Opencv,Perspective,Homography,我只是试图摆脱图像的透视,换句话说,我试图从2D图像中获得鸟瞰图图像,以便于计算图像中两点之间的距离。此时,使用OpenCV的cv2.warpPerspective方法获得的结果图像需要最终图像的大小作为参数,该参数未知且应静态给定,从而生成扭曲图像的裁剪图像。因此,我使用cv2.getPerspective方法计算源图像的角点,并用这些点计算新的单应性。在用这个单应矩阵和已知的最终图像大小生成一个新的扭曲图像后,我得到了没有任何裁剪的完整图像。我的大部分经验都相当成功,但在一些样本中却奇怪地失

我只是试图摆脱图像的透视,换句话说,我试图从2D图像中获得鸟瞰图图像,以便于计算图像中两点之间的距离。此时,使用OpenCV的cv2.warpPerspective方法获得的结果图像需要最终图像的大小作为参数,该参数未知且应静态给定,从而生成扭曲图像的裁剪图像。因此,我使用cv2.getPerspective方法计算源图像的角点,并用这些点计算新的单应性。在用这个单应矩阵和已知的最终图像大小生成一个新的扭曲图像后,我得到了没有任何裁剪的完整图像。我的大部分经验都相当成功,但在一些样本中却奇怪地失败了

以下是我正在做的:

  • 从相机图像中获取现实世界中已知矩形的4个点(点的顺序为:TL(左上)->TR(右上)->BR(右下)->BL(左下))
  • 计算这些点的边界框,并将其设置为通过上述步骤获得的源点的目标
  • 计算单应矩阵,得到单应矩阵
  • 使用此矩阵,计算源图像的角点,以便能够知道结果图像(扭曲图像)的大小
  • 由于我知道源图像角点的结果坐标,我计算了一个新的单应矩阵,并生成了具有已知大小的结果图像
成功的尝试如下所示。橙色点是真实矩形的点,红色矩形是目标点

下图是我用上述步骤计算的结果,效果很好。(它的大小调整为一个大图像)

获得的新角点位置一致:

TL:(-385,-308),TR:(1397,-326),BR:(906778),BL:(97776)

但在尝试不同的例子时,我遇到了一些失败的情况,如下所示:

由此产生的新角点如下所示,似乎不正确:TL:(54152218),TR:(-13144309),BR:(909360),BL:(318551)

顺便说一下,同形矩阵似乎完全正确。我测试过了,问题出在结果图像上。而且图像内部没有与这些点(称为消失点)相交的线,这可能导致这种结果图像

我留下源图像和代码片段来重现下面的结果。有一件小东西我正在看,但两天都找不到。提前谢谢

源图像:

守则:

import numpy as np
import cv2
import imutils

def warpImage(image, src_pts):
    height, width = image.shape[:2]

    min_rect = cv2.boundingRect(np.array(src_pts))
    dst = [[min_rect[0], min_rect[1]],
           [min_rect[0] + min_rect[2], min_rect[1]],
           [min_rect[0] + min_rect[2], min_rect[1] + min_rect[3]],
           [min_rect[0], min_rect[1] + min_rect[3]]]

    corners = [[0, 0], [width-1, 0], [width-1, height-1], [0, height-1]]

    src_np = np.float32(src_pts)
    dst_np = np.float32(dst)

    M = cv2.getPerspectiveTransform(src_np, dst_np)

    ptsss = np.float32([corners]).reshape(-1, 1, 2)

    scene_corners = cv2.perspectiveTransform(ptsss, M)

    min_col, min_row = 50000, 50000
    max_col, max_row = 0, 0
    i = 0
    for corner in scene_corners:
        if corner[0][0] > max_col:
            max_col = corner[0][0]
        if corner[0][1] > max_row:
            max_row = corner[0][1]
        if corner[0][0] < min_col:
            min_col = corner[0][0]
        if corner[0][1] < min_row:
            min_row = corner[0][1]
        i += 1

    new_dst = []
    for corner in scene_corners:
        pt = [int(corner[0][0] - min_col), int(corner[0][1] - min_row)]
        new_dst.append(pt)

    src2_np = np.float32(corners)
    dst2_np = np.float32(new_dst)

    M2 = cv2.getPerspectiveTransform(src2_np, dst2_np)
    warped_image = cv2.warpPerspective(image, M2, (max_col - min_col, max_row - min_row))

    return warped_image

img = cv2.imread("grid.png", 1)
img2 = img.copy()

# first one that works good
src1 = [[262, 129], [695, 130], [770, 350], [171, 352]]

cv2.circle(img, (src1[0][0], src1[0][1]), 3, (5, 140, 205), 3, 20)
cv2.circle(img, (src1[1][0], src1[1][1]), 3, (5, 140, 205), 3, 20)
cv2.circle(img, (src1[2][0], src1[2][1]), 3, (5, 140, 205), 3, 20)
cv2.circle(img, (src1[3][0], src1[3][1]), 3, (5, 140, 205), 3, 20)

cv2.imshow("img", img)

warped_img_1 = warpImage(img, src1)
warped_img_1_height, warped_img_1_width = warped_img_1.shape[:2]
if warped_img_1_width > warped_img_1_height:
    warped_img_1 = imutils.resize(warped_img_1, width=800)
else:
    warped_img_1 = imutils.resize(warped_img_1, height=800)
cv2.imshow("warped1", warped_img_1)

# second one that does not work
src2 = [[263, 260], [450, 302], [364, 394], [142, 321]]

cv2.circle(img2, (src2[0][0], src2[0][1]), 3, (5, 140, 205), 3, 20)
cv2.circle(img2, (src2[1][0], src2[1][1]), 3, (5, 140, 205), 3, 20)
cv2.circle(img2, (src2[2][0], src2[2][1]), 3, (5, 140, 205), 3, 20)
cv2.circle(img2, (src2[3][0], src2[3][1]), 3, (5, 140, 205), 3, 20)

cv2.imshow("img2", img2)

warped_img_2 = warpImage(img2, src2)
warped_img_2_height, warped_img_2_width = warped_img_2.shape[:2]
if warped_img_2_width > warped_img_2_height:
    warped_img_2 = imutils.resize(warped_img_2, width=800)
else:
    warped_img_2 = imutils.resize(warped_img_2, height=800)

cv2.imshow("warped2", warped_img_2)
cv2.waitKey()
将numpy导入为np
进口cv2
导入imutils
def图像(图像,src_pts):
高度,宽度=图像。形状[:2]
min_rect=cv2.boundingRect(np.array(src_pts))
dst=[[min_-rect[0],min_-rect[1]],
[min_-rect[0]+min_-rect[2],min_-rect[1]],
[min_rect[0]+min_rect[2],min_rect[1]+min_rect[3]],
[min_-rect[0],min_-rect[1]+min_-rect[3]]
角点=[[0,0],[width-1,0],[width-1,height-1],[0,height-1]]
src_np=np.float32(src_pts)
dst_np=np.32(dst)
M=cv2.getPerspectiveTransform(src_np,dst_np)
ptsss=np.float32([corners])。重塑(-1,1,2)
场景_角点=cv2.透视变换(ptsss,M)
最小列,最小行=50000,50000
最大列,最大行=0,0
i=0
对于场景中的角点,请执行以下操作:
如果角点[0][0]>最大值:
最大列=角[0][0]
如果角点[0][1]>最大行数:
最大行=角[0][1]
如果角点[0][0]<最小值:
最小值=角[0][0]
如果角点[0][1]<最小行:
最小行=角[0][1]
i+=1
新的_dst=[]
对于场景中的角点,请执行以下操作:
pt=[int(角点[0][0]-min\u列),int(角点[0][1]-min\u行)]
新数据附加(pt)
src2_np=np.32(角点)
dst2_np=np.float32(新的_dst)
M2=cv2.getPerspectiveTransform(src2\u np,dst2\u np)
扭曲的_图像=cv2。扭曲透视图(图像,M2,(最大列-最小列,最大列-最小列))
返回扭曲的图像
img=cv2.imread(“grid.png”,1)
img2=img.copy()
#第一个很好用的
src1=[[262129]、[695130]、[770350]、[171352]]
cv2.圆(img,(src1[0][0],src1[0][1]),3,(5140205),3,20)
cv2.圆(img,(src1[1][0],src1[1][1]),3,(5140205),3,20)
cv2.圆(img,(src1[2][0],src1[2][1]),3,(5140205),3,20)
cv2.圆(img,(src1[3][0],src1[3][1]),3,(5140205),3,20)
cv2.imshow(“img”,img)
warped_img_1=warpImage(img,src1)
翘曲的高度,翘曲的宽度=翘曲的形状1.形状[:2]
如果翘曲\u img\u 1\u宽度>翘曲\u img\u 1\u高度:
扭曲的图片1=imutils.resize(扭曲的图片1,宽度=800)
其他:
扭曲的图片1=imutils.resize(扭曲的图片1,高度=800)
cv2.imshow(“扭曲1”,扭曲1)
#第二个不起作用的
src2=[[263260]、[450302]、[364394]、[142321]]
cv2.圆(img2,(src2[0][0],src2[0][1]),3,(5140205),3,20)
cv2.圆(img2,(src2[1][0],src2[1][1]),3,(5140205),3,20)
cv2.圆(img2,(src2[2][0],src2[2][1]),3,(5140205),3,20)
cv2.圆(img2,(src2[3][0],src2[3][1]),3,(5140205),3,20)
cv2.imshow(“img2”,img2)
warped_img_2=warpImage(img2,src2)
翘曲的高度,翘曲的宽度=翘曲的形状2.形状[:2]
如果翘曲\u img\u 2\u宽度>翘曲\u img\u 2\u高度:
warped_img_2=imutils.resize(warped_img_2,width=800)
其他:
翘曲的\u img\u 2=imutils.resize(翘曲的\u img\u 2,高度=800)
cv2.imshow(“扭曲的2”,扭曲的2)
cv2.waitKey()

你能听懂吗

在src点和dst点之间画一条线。e、 基本法`

确保相关性相同。当然,它不应该生产这样的产品

如果不是因为错误的联想

而不是getperspectivetransform。尝试使用M,mask=cv.findHomography(src_pts,dst_pts,cv.RANSAC,5.0)