【问题标题】:Python cv2.WarpPerspective tranfromation shows Dashed linePython cv2.WarpPerspective 转换显示虚线
【发布时间】:2022-01-16 03:39:54
【问题描述】:

我用四个坐标取了两个虚拟目标点pts2和pts4,并实施了两次环绕透视变换。然后这些点的输出之间有一条虚线。

Python Code 

warped_mask = np.zeros((480,640,3),dtype="uint8") 
h_base, w_base = 480,640

white_subject =  np.ones((480,640,3),dtype="uint8")*255
h_white, w_white = white_subject.shape[:2]


pts2 = np.float32([[20, 20], [100, 20], [150, 300], [20, 250]])
pts3 = np.float32([[0, 0], [w_white, 0], [w_white, h_white], [0, h_white]])

transformation_matrix_white = cv2.getPerspectiveTransform(pts3, pts2)
warped_mask += cv2.warpPerspective(white_subject, transformation_matrix_white, (w_base, h_base)) 

pts4 = np.float32([[100, 20],[300,20], [300, 300], [150, 300]])

transformation_matrix_white = cv2.getPerspectiveTransform(pts3, pts4)
warped_mask += cv2.warpPerspective(white_subject, transformation_matrix_white, (w_base, h_base)) 

cv2.imshow("canvas", warped_mask)
cv2.waitKey(0)
cv2.destroyAllWindows()

输入主题作为设计图片

输出

请帮我把没有虚线的平滑缝合。

【问题讨论】:

  • 一条“细线”。一般是无法避免的。
  • 您可以尝试使用 openGL 纹理而不是单应性扭曲(取决于您的目标是否有意义)。你真的想/必须沿着一条线缝合吗?如果是,请确保两个输入图像之一中的每个像素都可用。在许多任务中,您将有重叠,其中两个输入图像中的像素都可用。在那里,您可以使用交叉混合或决定使用这两个值之一。
  • 目标是实现非仿射变换,使得输出的边缘没有虚线。如需参考,请访问此 repo github.com/GSNCodes/…

标签: python opencv image-processing computer-vision


【解决方案1】:

虚线是算术溢出的结果。

放大后,我们可以看到所有的值都是正数,但有些不是0也不是255:

在NumPy中求和(例如):uint8(255) + uint8(56)时,由于溢出,结果为55。
BGR = (55, 55, 55) 的像素值被视为深灰色。


在白色掩码示例中,我们希望在将正值添加到255 时得到255。

为避免溢出,您可以使用cv.add 而不是+=。
cv.add 具有溢出保护(它将结果剪辑为 255)。

将warped_mask += cv2.warpPerspective(white_subject, transformation_matrix_white, (w_base, h_base)) 替换为:

warped_mask = cv2.add(warped_mask, cv2.warpPerspective(white_subject, transformation_matrix_white, (w_base, h_base)))

使用时的结果:cv2.add:


使用该模式时,使用cv2.max而不是cv2.add时效果更好。

将warped_mask += cv2.warpPerspective(white_subject, transformation_matrix_white, (w_base, h_base)) 替换为:

warped_mask = cv2.max(warped_mask, cv2.warpPerspective(white_subject, transformation_matrix_white, (w_base, h_base)))

结果使用模式和cv2.max:


完整代码:

import cv2
import numpy as np

warped_mask = np.zeros((480,640,3),dtype="uint8")
h_base, w_base = 480,640

#white_subject =  np.ones((480,640,3),dtype="uint8")*255
white_subject = cv2.resize(cv2.imread('pattern.jpg'), (640, 480))
h_white, w_white = white_subject.shape[:2]


pts2 = np.float32([[20, 20], [100, 20], [150, 300], [20, 250]])
pts3 = np.float32([[0, 0], [w_white, 0], [w_white, h_white], [0, h_white]])

transformation_matrix_white = cv2.getPerspectiveTransform(pts3, pts2)
#warped_mask += cv2.warpPerspective(white_subject, transformation_matrix_white, (w_base, h_base)) 
warped_mask = cv2.max(warped_mask, cv2.warpPerspective(white_subject, transformation_matrix_white, (w_base, h_base)))

pts4 = np.float32([[100, 20],[300,20], [300, 300], [150, 300]])

transformation_matrix_white = cv2.getPerspectiveTransform(pts3, pts4)

#warped_mask += cv2.warpPerspective(white_subject, transformation_matrix_white, (w_base, h_base)) 
warped_mask = cv2.max(warped_mask, cv2.warpPerspective(white_subject, transformation_matrix_white, (w_base, h_base)))

cv2.imshow("canvas", warped_mask)
cv2.waitKey(0)
cv2.destroyAllWindows()

为了更好的效果,我们可能会添加填充:

import cv2
import numpy as np

warped_mask = np.zeros((480,640,3),dtype="uint8")
h_base, w_base = 480, 640

white_subject = np.ones((480,640,3),dtype="uint8")*255
white_subject = cv2.imread('pattern.jpg')
h_white, w_white = white_subject.shape[:2]

padded_warped_mask = np.pad(warped_mask, ((1, 1), (1, 1), (0, 0)), mode='edge')
padded_white_subject = np.pad(white_subject, ((1, 1), (1, 1), (0, 0)), mode='edge')

pts2 = np.float32([[20, 20], [100, 20], [150, 300], [20, 250]])
pts3 = np.float32([[0, 0], [w_white, 0], [w_white, h_white], [0, h_white]])


# Transform (0,0) coordinate to (1,1)
top2one = np.float64([[1,    0,   -1],
                      [0,    1,   -1],
                      [0,    0,    1]])

# Transform (1,1) coordinate to (0,0)
one2top = np.float64([[1,      0,    1],
                      [0,      1,    1],
                      [0,      0,    1]])


transformation_matrix_white = cv2.getPerspectiveTransform(pts3, pts2)

# Compensate the transformation for applying the padded two rows and columns
#transformation_matrix_white = one2top @ transformation_matrix_white @ top2one
transformation_matrix_white = top2one @ transformation_matrix_white @ one2top

#warped_mask = cv2.add(warped_mask, cv2.warpPerspective(padded_white_subject, transformation_matrix_white, (w_base, h_base)))
warped_mask = cv2.max(warped_mask, cv2.warpPerspective(padded_white_subject, transformation_matrix_white, (w_base, h_base)))

pts4 = np.float32([[100, 20],[300,20], [300, 300], [150, 300]])



transformation_matrix_white = cv2.getPerspectiveTransform(pts3, pts4)

# Compensate the transformation for applying the padded two rows and columns
#transformation_matrix_white = one2top @ transformation_matrix_white @ top2one
transformation_matrix_white = top2one @ transformation_matrix_white @ one2top

#warped_mask = cv2.add(warped_mask, cv2.warpPerspective(padded_white_subject, transformation_matrix_white, (w_base, h_base)))
warped_mask = cv2.max(warped_mask, cv2.warpPerspective(padded_white_subject, transformation_matrix_white, (w_base, h_base)))

cv2.imshow("canvas", warped_mask)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果:

【讨论】:

  • 感谢您的快速回复。我尝试了更高的维度,即 warped_mask = np.zeros((1000,1000,3),dtype="uint8") h_base, w_base = 1000,1000 ,用于不同的虚拟点,即 pts2 = np.float32([[20 , 20], [200, 20], [450, 700], [20, 250]]) 和 pts4 = np.float32([[200, 20],[500,20], [700, 700], [ 450, 700]]) 我得到了结果中的虚线。
  • 在什么配置下?有填充还是没有填充?使用白色主题或图案?请注意,答案仅适用于特定情况 - 它不应该是涵盖所有情况的通用解决方案。
  • 我使用它时没有填充图案。
  • 尝试使用填充。为什么你只尝试不使用填充?
  • 尝试了填充方法,减少了黑色虚线,但没有完全删除它。能否详细说明 top2one 和 one2top 变量的意义?
猜你喜欢
  • 2022-01-17
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-15
  • 2014-04-22
  • 1970-01-01
相关资源
最近更新 更多