python 如何使用平移矩阵将小图像的特定坐标转换为大图像的特定坐标

how to put a specific coordinate of a small image to a specific coordinate of a large image using translation matrix in python

我正在学习 OpenCV,我正在寻找 python 中的代码,它获取小图像的输入坐标并将其映射到大图像的坐标,以便将小图像插入到大图像,它可以像旋转一样变换。我想使用翻译矩阵作为输入来做到这一点。例如,如果矩阵是:

([75, 120][210,320],
 [30, 90][190,305],
 [56, 102][250,474],
 [110, 98][330,520])

表示小图(75, 120)处的像素映射到大图(210, 320)处的像素,小图(30, 90)处的像素映射到(190, 305) 大图 ... 我进行了很多搜索,但没有得到我的问题的正确答案。 我该如何解决这个问题?

我不知道在任何地方将像素映射到像素的矩阵运算,并且由于图像通常由二维数组表示,因此没有通用的方法使这些像素指向相同的数据。

但是鉴于这些图像由 NumPy 数组表示,您可以使用高级索引将任何像素从一个数组复制到另一个数组:

# smallimage is a NumPy array
# bigimage is a NumPy array

### Indices ###
# I formatted it so the matching indices
# between the 2 images line up in a column

bigD1 =   [210, 190, 250, 330] # dimension 0
bigD2 =   [320, 305, 474, 520] # dimension 1

smallD1 = [75,  30,  56,  110]
smallD2 = [120, 90,  102, 98]

### copy pixels from small image to big image ###

# on right side of =, advanced indexing copies
# the selected pixels to a new temporary array
#                                   v
bigimage[bigD1, bigD2] = smallimage[smallD1, smallD2]
#        ^
# on left side of =, advanced indexing specifies
# where we copy the temporary array's pixels to.

# smallimage is unchanged
# bigimage has edited pixels

在大图中插入小图:

import sys
import cv2

dir = sys.path[0]
small = cv2.imread(dir+'/small.png')
big = cv2.imread(dir+'/big.png')

x, y = 20, 20
h, w = small.shape[:2]
big[y:y+h, x:x+w] = small

cv2.imwrite(dir+'/out.png', big)

调整大小然后插入:

h, w = small.shape[:2]
small=cv2.resize(small,(w//2,h//2))

x, y = 20, 20
h, w = small.shape[:2]
big[y:y+h, x:x+w] = small

插入部分图片:

x, y = 20, 20
h, w = small.shape[:2]
hh, ww = h//2, w//2
big[y:y+hh, x:x+ww] = small[0:hh, 0:ww]

旋转样本:

bH, bW = big.shape[:2]
sH, sW = small.shape[:2]
ch, cw = sH//2, sW//2
x, y = sW-cw//2, ch

empty = 0 * np.ones((bH, bW, 3), dtype=np.uint8)
empty[y:y+sH, x:x+sW] = small

M = cv2.getRotationMatrix2D(center=(x+cw, y+ch), angle=45, scale=1)
rotated = cv2.warpAffine(empty, M, (bW, bH))
big[np.where(rotated != 0)] = rotated[np.where(rotated != 0)]

透视变换示例:

bH, bW = big.shape[:2]
sH, sW = small.shape[:2]
x, y = 0, 0

empty = 0 * np.ones((bH, bW, 3), dtype=np.uint8)
empty[y:y+sH, x:x+sW] = small

_inp = np.float32([[0, 0], [sW, 0], [bW, sH], [0, sH]])
_out = np.float32([[bW//2-sW//2, 0], [bW//2+sW//2, 0], [bW, bH], [0, bH]])
M = cv2.getPerspectiveTransform(_inp, _out)
transformed = cv2.warpPerspective(empty, M, (bH, bW))

big[np.where(transformed != 0)] = transformed[np.where(transformed != 0)]

最后是映射坐标;我想你只需要填写 _out:

bH, bW = big.shape[:2]
sH, sW = small.shape[:2]

empty = 0 * np.ones((bH, bW, 3), dtype=np.uint8)
empty[:sH, :sW] = small

# Cordinates: TopLeft, TopRight, BottomRight, BottomLeft
_inp = np.float32([[0, 0], [sW, 0], [sW, sH], [0, sH]])
_out = np.float32([[50, 40], [300, 40], [200, 200], [10, 240]])
M = cv2.getPerspectiveTransform(_inp, _out)
transformed = cv2.warpPerspective(empty, M, (bH, bW))

big[np.where(transformed != 0)] = transformed[np.where(transformed != 0)]