【opencv】5.5 几何变换-- 重映射 cv2.remap()

把一张图像内的像素点放置到另一幅图像内指定的位置,这个操作叫做重映射。
前两节学习的仿射变换和透视变换,是通过变换矩阵来指定映射方式。
有时我们希望通过自定义的方式来指定重映射。opencv 就为我们提供了一个自定义映射的函数 cv2.remap()

函数原型:

cv2.remap(src_img, map1, map2, interpolation)

参数:

  • src_img:原始图像
  • map1:目标图像中的每一个像素都对应于(映射于)原始图像的中的某个像素,将对应的原始图像的像素坐标的col存放在map1中。map1 的shape和目标图像一样。
  • map2:目标图像中的每一个像素都对应于(映射于)原始图像的中的某个像素,将对应的原始图像的像素坐标的row存放在map2中。map2 的shape和目标图像一样。
  • interpolation: 插值方式,不支持 INTER_AREA

说明:
目标图像的第一个像素,取原始图像中坐标为(2,2)的像素值 7
【opencv】5.5 几何变换-- 重映射 cv2.remap()_第1张图片

举例:
将目标图像中所有像素点的值都取原图像中的第0行第3列上的像素点

import cv2
import numpy as np

# 随机生成原始图像,大小为[4, 5]
src_img = np.random.randint(0, 256, size=[4, 5], dtype=np.uint8)
rows, cols = src_img.shape

# 指定原始图像的第3列,第0行
map1 = np.ones((4, 5), dtype=np.float32) * 3
map2 = np.ones((4, 5), dtype=np.float32) * 0

# 插值方式可解决索引值为float的问题
dst_img = cv2.remap(src_img, map1, map2, cv2.INTER_LINEAR)

print("src_img=\n", src_img)
print("\nmap1=\n", map1)
print("\nmap2=\n", map2)
print("\ndst_img=\n", dst_img)


# 输出为:
# src_img=
#  [[252  39  25 186  19]
#  [209 225  13 176 133]
#  [ 43 115  92 110 144]
#  [  3 176 208   8 232]]
# 
# map1=
#  [[3. 3. 3. 3. 3.]
#  [3. 3. 3. 3. 3.]
#  [3. 3. 3. 3. 3.]
#  [3. 3. 3. 3. 3.]]
# 
# map2=
#  [[0. 0. 0. 0. 0.]
#  [0. 0. 0. 0. 0.]
#  [0. 0. 0. 0. 0.]
#  [0. 0. 0. 0. 0.]]
# 
# dst_img=
#  [[186 186 186 186 186]
#  [186 186 186 186 186]
#  [186 186 186 186 186]
#  [186 186 186 186 186]]


复制图片

import cv2
import numpy as np

src_img = np.random.randint(0, 256, (4, 5), dtype=np.uint8)
rows, cols = src_img.shape[:2]

map1 = np.zeros_like(src_img, dtype=np.float32)
map2 = np.zeros_like(src_img, dtype=np.float32)

for i in range(rows):
    for j in range(cols):
        map1[i, j] = j
        map2[i, j] = i

dst_img = cv2.remap(src_img, map1, map2, cv2.INTER_LINEAR)

print(src_img)
# [[116   0  67 144  69]
#  [237  62   3  70 232]
#  [206 213   5 142 196]
#  [156  14 175 252  73]]

print(dst_img)
# [[116   0  67 144  69]
#  [237  62   3  70 232]
#  [206 213   5 142 196]
#  [156  14 175 252  73]]

说明:
1、map1, map2 的值都是浮点数,因此,目标图像可以映射回一个非整数的值,这意味着目标图像可以“反向映射”到原始图像中两个像素之间的位置(当然,该位置是不存在像素值的)。这时,可以采用不同的方法实现插值,函数中的interpolation 参数可以控制插值方式;正是由于 参数map1 和 参数map2 的值是浮点数,所以通过函数 cv2.remap() 所能实现的映射关系变得更加随意,可以通过自定义映射参数实现不同形式的映射。

2、定义 map1, map2 的时候,数据类型一定要指定为浮点数(dtype=np.float32), 否则会报错

你可能感兴趣的:(#,OpenCV,python,opencv,深度学习,机器学习,计算机视觉)