在warpPerspective之前,我在原始图像下找到了一组坐标/点,如何在经过透视校正的现在裁剪并校正后的图像中得到相应的点?
例如:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('sudoku.png')
rows,cols,ch = img.shape
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
point = np.array([[10,10]])
M = cv.getPerspectiveTransform(pts1,pts2)
dst = cv.warpPerspective(img,M,(300,300))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
如何获取img映射中的新坐标[10,10]到dst图像?
答案 0 :(得分:1)
您必须执行与图像上相同的转换(在数学上)。在这种情况下,这意味着使用cv2.perspectiveTransform
(请注意,输入点必须有1行,1列和2个通道-第一个是X,第二个Y坐标)。
此功能将转换所有输入点,但不执行和裁剪。您将需要对转换后的坐标进行后处理,并丢弃那些位于裁剪区域之外的坐标。在您的情况下,您想保留(0 <= x < 300) and (0 <= y < 300)
处的点。
示例代码:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('sudoku.png')
rows,cols,ch = img.shape
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
points = np.float32([[[10, 10]], [[116,128]], [[254,261]]])
M = cv.getPerspectiveTransform(pts1,pts2)
dst = cv.warpPerspective(img,M,(300,300))
# Transform the points
transformed = cv.perspectiveTransform(points, M)
# Perform the cropping -- filter out points that are outside the crop area
cropped = []
for pt in transformed:
x, y = pt[0]
if x >= 0 and x < dst.shape[1] and y >= 0 and y < dst.shape[0]:
print "Valid point (%d, %d)" % (x, y)
cropped.append([[x,y]])
else:
print "Out-of-bounds point (%d, %d)" % (x, y)
# Turn it back into a single numpy array
cropped = np.hstack(cropped)
# Visualize
plt.subplot(121)
plt.imshow(img)
for pt in points:
x, y = pt[0]
plt.scatter(x, y, s=100, c='red', marker='x')
plt.title('Input')
plt.subplot(122)
plt.imshow(dst)
for pt in transformed:
x, y = pt[0]
plt.scatter(x, y, s=100, c='red', marker='x')
plt.title('Output')
plt.show()
控制台输出:
Out-of-bounds point (-53, -63)
Valid point (63, 67)
Valid point (192, 194)
可视化: