几何变换之重映射---OpenCV-Python开发指南(14)
发布日期:2021-06-30 21:24:40 浏览次数:3 分类:技术文章

本文共 3612 字,大约阅读时间需要 12 分钟。

目录

什么是重映射

把一副图像内的像素点放置到另一幅图像内的指定位置,这个过程我们称为重映射。简单点理解,也就是copy一个图像到另一个图像中。

在OpenCV中,它给我们提供了cv2.remap()函数作为重映射,其定义如下:

def remap(src, map1, map2, interpolation, dst=None, borderMode=None, borderValue=None):

src:代表原始图像

map1:可以表示(x,y)点的一个映射,也可以表示CV_16SC2、CV_32FC1、CV_32FC2类型(x,y)点的x值

map2:当前map1表示(x,y)点的一个映射时,该值为空。当map1表示CV_16SC2、CV_32FC1、CV_32FC2类型(x,y)点的x值时,该值时CV_16UC1、CV_32FC1类型(x,y)点的y值。

interpolation,borderMode,borderValue与前文类似。

需要注意,map1指代的是像素点所在位置的列号,map2指代的是像素点所在位置的行号。

copy像素点

现在我们假设有一个需求,将目标图像内的所有像素点都映射为原始图像内的第100行,200列上的像素点。具体实现如下:

import cv2import numpy as npimg = cv2.imread("4.jpg")rows, cols, ch = img.shapemapx = np.ones(img.shape[:2], np.float32) * 200mapy = np.ones(img.shape[:2], np.float32) * 100result_img = cv2.remap(img, mapx, mapy, cv2.INTER_LINEAR)cv2.imshow("img", img)cv2.imshow("result_img", result_img)cv2.waitKey()cv2.destroyAllWindows()

如上面代码所示,我们将所有像素点都设置为原始图像(100,200)点的像素点,会得到一个非常纯色的图像,效果如下所示:

点像素设置

copy整个图像

那么既然能copy某个像素点,那么也肯定能copy整个图像。下面,我们将上图左边的图像全部copy到右边,具体代码如下:

import cv2import numpy as npimg = cv2.imread("4.jpg")rows, cols, ch = img.shapemapx = np.ones(img.shape[:2], np.float32)mapy = np.ones(img.shape[:2], np.float32)for i in range(rows):    for j in range(cols):        mapx.itemset((i,j),j)#设置每个点映射原图的Y坐标        mapy.itemset((i,j),i)#设置每个点映射原图的X坐标result_img = cv2.remap(img, mapx, mapy, cv2.INTER_LINEAR)cv2.imshow("img", img)cv2.imshow("result_img", result_img)cv2.waitKey()cv2.destroyAllWindows()

这里,我们将所有点映射到所有点,每个像素点一一对应,就完成了copy原图像。运行之后,效果如下所示:

copy

绕X轴翻转

通过cv2.remap()函数,我们不仅可以重映射像素点,还可以翻转过来映射,也就是通过它实现X轴的翻转效果,只要保证X轴不变,并且Y坐标值以X轴为对称进行交换即可。

修改上面代码中的某一行,代码如下:

import cv2import numpy as npimg = cv2.imread("4.jpg")rows, cols, ch = img.shapemapx = np.ones(img.shape[:2], np.float32)mapy = np.ones(img.shape[:2], np.float32)for i in range(rows):    for j in range(cols):        mapx.itemset((i,j),j)        mapy.itemset((i,j),rows-1-i)#修改这一行即可,对称result_img = cv2.remap(img, mapx, mapy, cv2.INTER_LINEAR)cv2.imshow("img", img)cv2.imshow("result_img", result_img)cv2.waitKey()cv2.destroyAllWindows()

运行之后,我们得到了绕X轴翻转的图像,效果如下:

绕X轴翻转

绕Y轴翻转

既然我们可以通过cv2.remap()函数绕X翻转,那么肯定的也可以绕Y轴翻转,只要将X坐标值以Y轴为对称进行交换即可。

话不多说,直接上代码:

import cv2import numpy as npimg = cv2.imread("4.jpg")rows, cols, ch = img.shapemapx = np.ones(img.shape[:2], np.float32)mapy = np.ones(img.shape[:2], np.float32)for i in range(rows):    for j in range(cols):        mapx.itemset((i,j),cols-1-j)#修改这一行即可        mapy.itemset((i,j),i)#result_img = cv2.remap(img, mapx, mapy, cv2.INTER_LINEAR)cv2.imshow("img", img)cv2.imshow("result_img", result_img)cv2.waitKey()cv2.destroyAllWindows()

运行之后,我们得到绕Y轴翻转的图像:

绕Y轴翻转

绕XY轴翻转

那么绕XY轴一起翻转呢?这里二行代码一起更改:

import cv2import numpy as npimg = cv2.imread("4.jpg")rows, cols, ch = img.shapemapx = np.ones(img.shape[:2], np.float32)mapy = np.ones(img.shape[:2], np.float32)for i in range(rows):    for j in range(cols):        mapx.itemset((i,j),cols-1-j)        mapy.itemset((i,j),rows-1-i)result_img = cv2.remap(img, mapx, mapy, cv2.INTER_LINEAR)cv2.imshow("img", img)cv2.imshow("result_img", result_img)cv2.waitKey()cv2.destroyAllWindows()

运行之后,效果如下所示:

绕XY轴翻转

压缩一半

也就是将原图缩小一般,按将Y轴缩小一般,只需要将X轴设置为2倍即可。具体代码如下所示:

import cv2import numpy as npimg = cv2.imread("4.jpg")rows, cols, ch = img.shapemapx = np.ones(img.shape[:2], np.float32)mapy = np.ones(img.shape[:2], np.float32)for i in range(rows):    for j in range(cols):        mapx.itemset((i,j),j)        mapy.itemset((i,j),2*i)#修改这行代码即可result_img = cv2.remap(img, mapx, mapy, cv2.INTER_LINEAR)cv2.imshow("img", img)cv2.imshow("result_img", result_img)cv2.waitKey()cv2.destroyAllWindows()

运行之后,效果显示如下:

压缩原图像

既然能压缩,意味着也可以实现缩小,缩小的具体实现,可以当作训练的习题,方便大家巩固掌握,博主在这里就不在赘述了。

转载地址:https://liyuanjinglyj.blog.csdn.net/article/details/113807048 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:常规5大阈值处理---OpenCV-Python开发指南(15)
下一篇:几何变换之透视---OpenCV-Python开发指南(13)

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月29日 12时19分21秒