OpenCV实现常见的四种图像几何变换

目录
  • 准备图片
  • 1. 缩放 cv2.resize()方法
  • 2. 翻转 cv2.flip()方法
  • 3. 仿射变换 warpAffine()方法
    • 3.1 平移
    • 3.2 旋转
    • 3.3 倾斜
  • 4. 透视

准备图片

选择一张shape为(500,500,3)的梵高的《星月夜》以便示例。

1. 缩放 cv2.resize()方法

cv2.resize(src, dsize, dst=None, fx=None, fy=None, interpolation=None)

src 原图(的数组)

dsize: 输出图像的大小 格式:(a,b)。

设定dsize后就无需再设置fx和fy

fx 可选参数 水平方向缩放比

fy 可选参数 垂直方向缩放比

fx和fy不同于dsize,fx和fy是各是一个比值,如设为2,则表示放大2倍,设为1/2则表示缩小到原来的1/2

import cv2
img = cv2.imread("The_Starry_Night.jpg")

dst1 = cv2.resize(img, (200, 200))
dst2 = cv2.resize(img, (900, 900))
cv2.imshow("img", img)
cv2.imshow("dst1", dst1)
cv2.imshow("dst2", dst2)
cv2.waitKey()
cv2.destroyAllWindows()

执行结果如图所示,相比原图,图像得到了指定大小的缩小与放大。

使用fx和fy参数,则需要手动把dsize设为None。

import cv2
img = cv2.imread("The_Starry_Night.jpg")
# 将宽缩小到原来的1/3、高缩小到原来的1/2
dst3 = cv2.resize(img, None, fx=1 / 3, fy=1 / 2)
# 将宽高扩大2倍
dst4 = cv2.resize(img, None, fx=2, fy=2)
cv2.imshow("img", img)
cv2.imshow("dst3", dst3)
cv2.imshow("dst4", dst4)
cv2.waitKey()
cv2.destroyAllWindows()

结果呈现:

2. 翻转 cv2.flip()方法

flip(src, flipCode, dst=None)

src 图像(数组)

flipCode 翻转代码。可以是0,正数,负数。0表示沿X轴(水平方向的轴)翻转。1表示沿Y轴(竖直方向的轴)翻转。

负数表示同时沿X轴和Y轴翻转。

讲原图经过着三种翻转后,与原图拼在一块,呈现出了这种奇观:

import cv2
img = cv2.imread("The_Starry_Night.jpg")
dst1 = cv2.flip(img, 0)
dst2 = cv2.flip(img, 1)
dst3 = cv2.flip(img, -1)
cv2.imshow("img", img)
cv2.imshow("dst1", dst1)
cv2.imshow("dst2", dst2)
cv2.imshow("dst3", dst3)
cv2.waitKey()
cv2.destroyAllWindows()

将翻转结果放在同一张画布中

import cv2
import numpy as np
img = cv2.imread("The_Starry_Night.jpg")
dst1 = cv2.flip(img, 0)
dst2 = cv2.flip(img, 1)
dst3 = cv2.flip(img, -1)
a, b, c = img.shape
canvas = np.ones((2 * a, 2 * b, c), np.uint8) * 255
canvas[0:b, 0:a] = img
canvas[b:2*b, 0:a] = dst1
canvas[0:b, a:2*a] = dst2
canvas[b:2*b, a:2*a] = dst3
cv2.imshow("pic", canvas)
cv2.waitKey()
cv2.destroyAllWindows()
# 保存图片
# cv2.imwrite("final_pic", canvas)

结果呈现:

3. 仿射变换 warpAffine()方法

常见的仿射变换有平移,旋转和倾斜变换。

仿射变换使用cv2.warpAffine()方法完成

warpAffine(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)

src 原图

M 是一个二行三列的矩阵,也称仿射矩阵。warpAffine方法根据此矩阵的值来变换像素的位置。

M = [[a, b, c], [d, e, f]],则像素的变换公式为:

X = x × a + y × b + c

Y = x × d + y × e + f

其中x,y指原像素的x、y轴坐标。X,Y指变换后的X,Y坐标。

dsize 输出图像的尺寸。(不带放缩,增大的部分用黑色色素(0)填充)

这三个参数是常用的参数。其余参数建议使用默认值。

flags表示插入方式,borderMode是边界类型,borderValue表示边界值(默认0)。dst表示反射变换后输出的图像。

3.1 平移

以将《星月夜》向左平移50个像素,向下平移100个像素为例。

则M数组应写为[[1, 0, 50], [0, 1, 100]]:

import cv2
import numpy as np
img = cv2.imread("The_Starry_Night.jpg")
rows = len(img)
cols = len(img[0])
M = np.float32([[1, 0, 50],
                [0, 1, 100]])
dst = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow("img", img)
cv2.imshow("dst", dst)
cv2.waitKey()
cv2.destroyAllWindows()

如图所示,图像按照我们的预期成功被平移。

只是这样得到的图像有色素损失,我们丢失了超出画布之外的数据。

为了避免损失,可以取设置dsize参数来控制输出图像的大小。

修改后的代码如下:

import cv2
import numpy as np
img = cv2.imread("The_Starry_Night.jpg")
rows = len(img)
cols = len(img[0])
M = np.float32([[1, 0, 50],
                [0, 1, 100]])
dst = cv2.warpAffine(img, M, (cols+200, rows+200))
cv2.imshow("img", img)
cv2.imshow("dst", dst)
cv2.waitKey()
cv2.destroyAllWindows()

优化后的程序执行效果:

3.2 旋转

旋转也是通过M矩阵来实现的,这个矩阵的运算较复杂,

OpenCV提供了getRotationMatrix2D()方法来计算旋转操作的M矩阵

getRotationMatrix2D(center, angle, scale)

center 指旋转中心的坐标

angle指旋转的角度

scale值缩放的比例。(旋转过程支持缩放)

import cv2
img = cv2.imread("The_Starry_Night.jpg")
rows = len(img)
cols = len(img[0])
center = (rows / 2, cols / 2)
M = cv2.getRotationMatrix2D(center, 30, 0.8)
dst = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow("img", img)
cv2.imshow("dst", dst)
cv2.waitKey()
cv2.destroyAllWindows()

旋转效果如图所示:

3.3 倾斜

OpenCV需要定位到图像的三个点的位置来计算倾斜效果,即左上角,右上角和左下角。

图像的倾斜也是根据M矩阵实现,得出矩阵的运算较复杂,通过getAffineTransform 方法实现。

语法

getAffineTransform(src, dst)

src是原图像的左上角,右上角和左下角三个点的坐标。三维数组格式,形如[[a, b], [c, d], [e, f]]。

dst是倾斜后这三个点预期的坐标。格式同上。

要保持左上,右下,左下三个点的顺序不能乱。

以将《星月夜》保持左下角和右上角坐标不变,左上角((0,0)处)向右移动150个像素长度。

代码如下:

import cv2
import numpy as np
img = cv2.imread("The_Starry_Night.jpg")
rows = len(img)
cols = len(img[0])
p1 = np.array([[0, 0], [cols - 1, 0], [0, rows - 1]], dtype=np.float32)
p2 = np.array([[150, 0], [cols - 1, 0], [0, rows - 1]], dtype=np.float32)
M = cv2.getAffineTransform(p1, p2)
dst = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow('img', img)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()

程序执行效果如下:

4. 透视

透视的实现使用的是warpPerspective()方法,而不再是用于平移、旋转、倾斜的warpAffine()方法。

使用warpPerspective()方法也需要通过M矩阵来计算透视效果,计算透视的M矩阵可以使用getPerspectiveTransform()方法。

getPerspectiveTransform(src, dst, solveMethod=None)

该方法常用的参数有两个,分别为原图的四个点的坐标(scr) 和 透视后四个点的坐标(dst)。Opcv需要通过定位图像的这四个点来计算透视效果。四个点依次为左上,右上,左下,右下。

坐标格式为二维数组格式,形如[[a, b],[c, d],[e, f],[g, h]]。

示例代码如下:

import cv2
import numpy as np
img = cv2.imread("The_Starry_Night.jpg")
rows = len(img)
cols = len(img[0])
# 原图的四点坐标
p1 = np.zeros((4, 2), np.float32)
p1[0] = [0, 0]
p1[1] = [cols - 1, 0]
p1[2] = [0, rows - 1]
p1[3] = [cols - 1, rows - 1]
# 透视后的四点坐标
p2 = np.zeros((4, 2), np.float32)
p2[0] = [150, 0]
p2[1] = [cols - 150, 0]
p2[2] = [0, rows - 1]  # 不变
p2[3] = [cols - 1, rows - 1]  # 不变
M = cv2.getPerspectiveTransform(p1, p2)
dst = cv2.warpPerspective(img, M, (cols, rows))
cv2.imshow('The_Starry_Night', img)
cv2.imshow('The_Starry_Night2', dst)
cv2.waitKey()
cv2.destroyAllWindows()

展示原图和透视后的图像效果:

到此这篇关于OpenCV实现常见的四种图像几何变换的文章就介绍到这了,更多相关OpenCV图像几何变换内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • OpenCV图像处理之七种常用图像几何变换

    0 程序环境与所学函数 本章程序运行需要导入下面三个库,并定义了一个显示图像的函数 所学函数 ##放大.缩小 cv.resize(img,dsize,[interpolation]) ##平移变换 M = np.array([[...]], dtype=np.float32) cv.warpAffine(img, M, dsize) ##镜像变换 cv.flip(img, 1) # 垂直镜像 cv.flip(img, 0) # 水平镜像 cv.flit(img, -1) # 水平垂直同时进行 #

  • Python3+OpenCV2实现图像的几何变换(平移、镜像、缩放、旋转、仿射)

    前言 总结一下最近看的关于opencv图像几何变换的一些笔记. 这是原图: 1.平移 import cv2 import numpy as np img = cv2.imread("image0.jpg", 1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] mode = imgInfo[2] dst = np.zeros(imgInfo, np.uint8) for i in range( height ): f

  • OpenCV图像几何变换之透视变换

    本文实例为大家分享了Android九宫格图片展示的具体代码,供大家参考,具体内容如下 1. 基本原理 透视变换(Perspective Transformation)的本质是将图像投影到一个新的视平面,其通用变换公式为: (u,v)为原始图像像素坐标,(x=x'/w',y=y'/w')为变换之后的图像像素坐标.透视变换矩阵图解如下: 仿射变换(Affine Transformation)可以理解为透视变换的特殊形式.透视变换的数学表达式为: 所以,给定透视变换对应的四对像素点坐标,即可求得透视变

  • opencv实现图像几何变换

    本文实例为大家分享了opencv实现图像几何变换的具体代码,供大家参考,具体内容如下 图像伸缩(cv2.resize) 图像的扩大与缩小有专门的一个函数,cv2.resize(),那么关于伸缩需要确定的就是缩放比例,可以是x与y方向相同倍数,也可以单独设置x与y的缩放比例.另外一个就是在缩放以后图像必然就会变化,这就又涉及到一个插值问题.那么这个函数中,缩放有几种不同的插值(interpolation)方法,在缩小时推荐cv2.INTER_ARER,扩大是推荐cv2.INTER_CUBIC和cv

  • Python实现图像几何变换

    本文实例讲述了Python实现图像几何变换的方法.分享给大家供大家参考.具体实现方法如下: import Image try: im=Image.open('test.jpg') #out = im.resize((128, 128)) #改变大小 #out = im.rotate(45) #45°旋转 #out = im.transpose(Image.FLIP_LEFT_RIGHT) #水平翻转 #out = im.transpose(Image.FLIP_TOP_BOTTOM) #垂直翻转

  • Python图像处理之几何变换

    目录 一.图像几何变换 二.图像平移 三.图像缩放 四.图像旋转 五.总结 一.图像几何变换 图像几何变换不改变图像的像素值,在图像平面上进行像素变换.适当的几何变换可以最大程度地消除由于成像角度.透视关系乃至镜头自身原因所造成的几何失真所产生的负面影响.几何变换常常作为图像处理应用的预处理步骤,是图像归一化的核心工作之一[1]. 一个几何变换需要两部分运算: 空间变换:包括平移.缩放.旋转和正平行投影等,需要用它来表示输出图像与输入图像之间的像素映射关系. 灰度插值算法:按照这种变换关系进行计

  • OpenCV实现常见的四种图像几何变换

    目录 准备图片 1. 缩放 cv2.resize()方法 2. 翻转 cv2.flip()方法 3. 仿射变换 warpAffine()方法 3.1 平移 3.2 旋转 3.3 倾斜 4. 透视 准备图片 选择一张shape为(500,500,3)的梵高的<星月夜>以便示例. 1. 缩放 cv2.resize()方法 cv2.resize(src, dsize, dst=None, fx=None, fy=None, interpolation=None) src 原图(的数组) dsize:

  • Android 常见的四种对话框实例讲解

    1.对话框通知(Dialog Notification) 当你的应用需要显示一个进度条或需要用户对信息进行确认时,可以使用对话框来完成. 下面代码将打开一个如图所示的对话框: public void click1(View view) { AlertDialog.Builder builder = new Builder(this); builder.setTitle("工学1号馆"); builder.setIcon(R.drawable.ic_launcher); builder.

  • 常见的四种POST 提交数据方式(小总结)

    HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS.GET.HEAD.POST.PUT.DELETE.TRACE.CONNECT 这几种.其中,POST 一般用来向服务端提交数据,本文主要讨论 POST 提交数据的几种方式. 我们知道,HTTP 协议是以 ASCII 码传输,建立在 TCP/IP 协议之上的应用层规范.规范把 HTTP 请求分为三个部分:状态行.请求头.消息主体.类似于下面形式: <method> <request-URL> <version&

  • Python实现排序方法常见的四种

    1.冒泡排序,相邻位置比较大小,将比较大的(或小的)交换位置 def maopao(a): for i in range(0,len(a)): for j in range(0,len(a)-i-1): if a[j]>a[j+1]: temp = a[j+1] a[j+1] = a[j] a[j] = temp #print(a) #print(a) print(a) 2.选择排序,遍历选择一个最小的数与当前循环的第一个数交换 def xuanze(a): for i in range(0,l

  • java性能优化四种常见垃圾收集器汇总

    目录 前言 常见的垃圾回收器和算法 serial 串行垃圾收集器 Parallel 多线程垃圾收集器 CMS 收集器 G1 收集器 显式垃圾收集 前言 本篇文章我们来具体看看如何选择合适的垃圾收集器.每种垃圾收集器都有其不同的算法实现和步骤,下面我们简单描述下我们常见的四种垃圾收集器的算法过程,感兴趣的同学们最好先看下以下的两篇文章去增加理解.分别介绍了一些垃圾回收的基本概念,和各种垃圾回收器回收的过程,内容重复,本章不会在去单独讲解一遍.所以本章做一些归纳总结. JVM GC 垃圾收集梳理总结

  • 详解C#批量插入数据到Sqlserver中的四种方式

    本篇,我将来讲解一下在Sqlserver中批量插入数据. 先创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的是GUID,表中没有创建任何索引.GUID必然是比自增长要快的,因为你生成一个GUID算法所花的时间肯定比你从数据表中重新查询上一条记录的ID的值然后再进行加1运算要少.而如果存在索引的情况下,每次插入记录都会进行索引重建,这是非常耗性能的.如果表中无可避免的存在索引,我们可以通过先删除索引,然后批量插入,最后再重建索引的方式来提高效率. create database C

  • Python+OpenCV 图像边缘检测四种实现方法

    目录 1.Sobel算子 2.Schaar算子(更能体现细节) 3.Laplacian算子(基于零穿越的,二阶导数的0值点) 4.Canny边缘检测(被认为是最优的边缘检测算法) 总结 import cv2 as cv import numpy as np import matplotlib.pyplot as plt # 设置兼容中文 plt.rcParams['font.family'] = ['sans-serif'] plt.rcParams['font.sans-serif'] = [

  • python3读取图片并灰度化图片的四种方法(OpenCV、PIL.Image、TensorFlow方法)总结

    在处理图像的时候经常是读取图片以后把图片转换为灰度图.作为一个刚入坑的小白,我在这篇博客记录了四种处理的方法. 首先导入包: import numpy as np import cv2 import tensorflow as tf from PIL import Image 方法一:在使用OpenCV读取图片的同时将图片转换为灰度图: img = cv2.imread(imgfile, cv2.IMREAD_GRAYSCALE) print("cv2.imread(imgfile, cv2.I

随机推荐