【问题标题】:Image Warping Python图像变形 Python
【发布时间】:2021-04-15 13:17:53
【问题描述】:

我有以下两张图片: source Image destination Image

我想使用投影变换将源图像变形为目标图像中的第一个(左)形状,并将源图像变形为目标图像中的第二个(右)形状。 所以我所做的是首先找到兴趣点:

src_interest_pts=np.float32([[0, 0],[0, 640],[480,0],[480, 640]]) 这是我图像的角落

Affine_interest_pts= np.float32([[41,215],[849,54],[602,458],[608,300]]) 是正确形状的角

Projective_interest_pts= np.float32([[195, 56],[494,158],[36, 183],[432, 498]])

并编写了以下代码:

img = cv2.imread("Q3/Dylan.jpg")
frame=cv2.imread("Q3/frames.jpg")
rows,cols,ch = frame.shape

src_interest_pts = np.float32([[0, 0],[0, 640],[480,0],[480, 640]])
Affine_interest_pts = np.float32([[41,215],[849,54],[602,458],[608,300]])
Projective_interest_pts = np.float32([[195, 56],[494,158],[36, 183],[432, 498]])

M = cv2.getAffineTransform(src_interest_pts ,Affine_interest_pts)
Affinedst = cv2.warpAffine(img,M,(cols,rows))

M=cv2.getPerspectiveTransform(src_interest_pts ,Projective_interest_pts)
Projectivedst=cv2.warpPerspective(img,M,(cols,rows))

dst=Affinedst+Projectivedst
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

结果是 getAffineTransform 返回错误,因为从源到目的地必须有 3 个兴趣点,但在我的情况下有 4 个。

删除我们得到的仿射代码后:

   src_interest_pts = np.float32([[0, 0],[0, 640],[480,0],[480, 640]])
   Projective_interest_pts = np.float32([[195, 56],[494,158],[36, 183],[432, 498]])
   M=cv2.getPerspectiveTransform(src_interest_pts ,Projective_interest_pts)
   Projectivedst=cv2.warpPerspective(img,M,(cols,rows))
   plt.subplot(121),plt.imshow(frame),plt.title('The frame')
   plt.subplot(122),plt.imshow(Projectivedst),plt.title('Warped')
   plt.show()

这是我得到的输出图像: Output Image

我的问题是:

我如何获得所需的输出?

也许我的问题出在兴趣点上?

为什么 getAffineTransform 不适用于第二个(右)形状?对于这种翘曲,我必须仅使用仿射变换进行翘曲。

编辑:

我将点改为:

pts1 = np.float32([[0, 0],[640, 0],[0,480],[640, 480]])
# ptsAffine = np.float32([[215,41],[54,849],[458,602],[300,608]])
ptsProjective = np.float32([[55, 195],[158,494],[183, 36],[498, 432]])

正如@fmw42 在他的评论中指出的那样,我一直在索引之间切换(x 中的内容应该在 y 中,反之) 但我仍然得到这个输出我想我很难找出正确的点。 output

【问题讨论】:

  • 请发布确切的错误消息以及它在您的代码中出现的位置。我认为问题在于您已将点定义为 y,x 并且需要在您的 np.float32 数组中将它们定义为 x,y 。您的输入是 width=640 和 height=480,但您将第二个点指定为 0,640。那将是 x=0,y=640。但它应该是 x=640 和 y=0,所以 640,0。查看您的仿射点,您列出的第一个是 41,215。但这不是靠近右侧四边形的任何地方。它接近左四边形,但在我看来并不好,215,41 也不是。所以你的输出点没有准确测量
  • 您的另一个问题是您需要使用 estimateAffine2D 代替 getAffineTransform
  • 感谢您的回答,我想我没有使用正确的积分!

标签: python opencv computer-vision transform


【解决方案1】:

正如我在我的 cmets 中提到的,您有几个问题。您的点定义不正确,您需要使用estimateAffine2D 代替getAffineTransform。这在 Python/OpenCV 中适用于我。

输入:

输出帧:

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread("Dylan.jpg")
frame=cv2.imread("frames.jpg")
rows,cols,ch = frame.shape

# x,y points are cw from top left
src_interest_pts = np.float32([[0,0],[640,0],[640,480],[0,480]])
Affine_interest_pts = np.float32([[551,224],[843,67],[903,301],[608,455]])
Projective_interest_pts = np.float32([[195,56],[494,158],[432,498],[36,183]])

M = cv2.estimateAffine2D(src_interest_pts ,Affine_interest_pts)[0]
Affinedst = cv2.warpAffine(img,M,(cols,rows))

M=cv2.getPerspectiveTransform(src_interest_pts ,Projective_interest_pts)
Projectivedst=cv2.warpPerspective(img,M,(cols,rows))

dst=Affinedst+Projectivedst
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

结果:

【讨论】:

    【解决方案2】:

    Opencv 仿射变换函数需要三个源点和目标点来获得仿射 2x3 矩阵。您还可以找到超定方程组的近似仿射变换。试试这个函数来为给定的问题生成仿射变换矩阵

    def affine(x, y):
        b = np.array([y[0][0], y[0][1], y[1][0], y[1][1], y[2][0], y[2][1], y[3][0], y[3][1]])
        A = np.array([[x[0][0], x[0][1], 1, 0, 0, 0],[0, 0, 0, x[0][0], x[0][1], 1],
        [x[1][0], x[1][1], 1, 0, 0, 0],[0, 0, 0, x[1][0], x[1][1], 1],
        [x[2][0], x[2][1], 1, 0, 0, 0],[0, 0, 0, x[2][0], x[2][1], 1],
        [x[3][0], x[3][1], 1, 0, 0, 0],[0, 0, 0, x[3][0], x[3][1], 1]])
    
        coef = np.linalg.inv(A.T @ A) @ A.T @ b
        M = np.array([[coef[0], coef[1], coef[2]],[coef[3], coef[4], coef[5]]], dtype=np.float64)
        return M
    

    试着这样称呼它:

    rows,cols,ch = frame.shape
    
    src_interest_pts = np.float32([[0, 0],[640,0],[640,480], [0,480]])
    Affine_interest_pts = np.float32([[548,215],[849,54],[908,300],[602,458]])
    Projective_interest_pts = np.float32([[195, 56],[494,158],[432, 498],[36, 183]])
    
    M = affine(src_interest_pts, Affine_interest_pts)
    Affinedst = cv2.warpAffine(img,M,(cols,rows))
    
    M=cv2.getPerspectiveTransform(src_interest_pts ,Projective_interest_pts)
    Projectivedst=cv2.warpPerspective(img,M,(cols,rows))
    
    dst=Affinedst+Projectivedst
        
        plt.subplot(121),plt.imshow(img),plt.title('Input')
        plt.subplot(122),plt.imshow(dst),plt.title('Output')
        plt.show()
    

    你会得到这样的输出。我希望这能解决你的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-15
      • 2020-01-15
      • 2019-01-26
      • 2012-09-26
      相关资源
      最近更新 更多