计算机视觉6:几何变换

1. 图像平移

图像平移是将一幅图像中所有的点都按照指定的平移量在水平、垂直方向移动,平移后的图像与原图像相同。

平移变换分两种类型:一种是图像大小不改变,这样最后原图像中会有一部分不在图像中;一种是图像大小改变,这样可以保全原图像的内容。

有了OpenCV后,平移图像就不需要如此麻烦了,因为OpenCV提供了函数warpAffine,该函数使用指定的矩阵变换源图像,声明如下:

warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) → dst

  • src:表示输入的图像;
  • M:表示2*3变换矩阵;
  • dsize:表示输出图像的大小;
  • dst:表示大小为dsize且类型与src相同的输出图像;
  • flags:表示插值方法的组合;
  • borderMode:表示边界模式;
  • borderValue:表示在边界为常量的情况下使用的值,默认为0。

代码实例:实现图像平移

import numpy as np
import cv2 as cv

img = cv.imread(r'test.jpg', 1)
rows, cols, channels = img.shape  # 获取图像的行数、列数和通道数

# 创建一个仿射变换矩阵M。这个矩阵定义了一个线性变换,
# 其中:
# 第一列 [1, 0] 表示x坐标的缩放因子和偏移量。
# 第二列 [0, 1] 表示y坐标的缩放因子和偏移量。
# 这里,图像将在x方向上平移100个像素,在y方向上平移50个像素。
M = np.float32([[1,0,100],[0,1,50]])

res = cv.warpAffine(img, M, (cols, rows))
cv.imshow('img', res)
cv.waitKey(0)
cv.destroyAllWindows()

效果图:

2. 图像旋转

图像的旋转变换时图像的位置变换,旋转后图像的大小一般会改变。

旋转前和旋转后的点离中心的位置不变。

可以利用OpenCV提供的库函数getRotationMatrix2D来实现图像旋转。还函数用来计算出旋转矩阵,声明如下:

getRotationMatrix2D(center, angle, scale) →  retval

  • center:表示旋转的中心点;
  • angle:表示旋转的角度;
  • scale:表示图像缩放因子。

代码实例1:实现图像的旋转

import cv2
import numpy as np

img=cv2.imread('test.jpg')
# 获取图像的行数和列数,这里使用img.shape获取图像的维度信息,并切片前两个元素。
rows,cols=img.shape[:2]

# 缩放因子,这里设置为1.2,表示旋转后的图像大小将是原始大小的1.2倍。
M=cv2.getRotationMatrix2D((cols/2,rows/2),60,1.2)
#第一个参数是旋转中心,第二个参数是旋转角度,第三个因子是旋转后的缩放因子

shuchu=cv2.warpAffine(img,M,(2*cols,rows)) # 第三个参数是输出图像的尺寸中心,图像的宽和高
while(1):
    cv2.imshow('Result',shuchu)
    if cv2.waitKey(1)&0xFF==27:   # ,27是Esc键的按键码。如果按下Esc键,则退出循环。
        break
cv2.destroyAllWindows()

代码效果图:

代码实例2:不出现裁剪的旋转

import cv2
import numpy as np
img=cv2.imread('test.jpg')
 
def rotate_bound(image, angle):
    # 抓取图像的尺寸,然后确定中心
    (h, w) = image.shape[:2]      # 获取图像的高度和宽度。
    (cX, cY) = (w // 2, h // 2)   # 计算图像的中心坐标

    # 获取旋转矩阵,使用中心点和旋转角度。负值表示顺时针旋转。
    M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0)
    cos = np.abs(M[0, 0])   # 获取旋转矩阵中x轴的缩放因子。
    sin = np.abs(M[0, 1])   # 获取旋转矩阵中y轴的缩放因子。
 
    # 计算图像的新边界尺寸
    nW = int((h * sin) + (w * cos))   # 计算新的宽度。
    nH = int((h * cos) + (w * sin))   # 计算新的高度。
 
    # 调整旋转矩阵以考虑平移
    M[0, 2] += (nW / 2) - cX
    M[1, 2] += (nH / 2) - cY
 
    # 执行实际旋转并返回图像
    shuchu=cv2.warpAffine(image, M, (nW, nH))
    while (1):
        cv2.imshow('shuchu', shuchu)
        if cv2.waitKey(1) & 0xFF == 27:
            break
 
rotate_bound(img,45)
 

代码效果:

3. 仿射变换

仿射变换是一种常用的图像几何变换。平移,旋转,缩放,翻转,剪切等变换都属于仿射变换。仿射变换的功能是从二维坐标到二维坐标之间的线性变换,且保持二维图形的“平直性”和“平行性”。

在OpenCV中,进行仿射变换的函数是warp Affine,声明如下:

warp Affine(src,M,dsize[,dest[,flags[,boederModel[,borderValue]]]])→dest

src:表示输入图像;

dest:表示输出图像,尺寸由dsize指定,图像类型与原图像一致;

M:表示2×3的变换矩阵;

dsize:指定图像输出尺寸;

flags:表示插值算法标识符,如果为WARP-INVERSE-MVP,则默认值INTER_LINEAR;borderMode表示边缘像素模式,有默认值BORDER-CONSTANT;

border Value:表示边界取值,有默认值Scalar(),即0

代码实例:实现图像的仿射变换

import numpy as np
import cv2 as cv

img = cv.imread(r'test.jpg', 1)
rows, cols, channels = img.shape
# 定义图像原始位置的三个角点(左上、右上、左下)。
p1 = np.float32([[0,0], [cols-1,0], [0,rows-1]])
# 定义这三个角点映射到的新位置。
p2 = np.float32([[0,rows*0.3], [cols*0.8,rows*0.2], [cols*0.15,rows*0.7]])
# 使用OpenCV的getAffineTransform函数计算仿射变换矩阵M,它将p1中的点映射到p2中的点。
M = cv.getAffineTransform(p1, p2)
# 使用OpenCV的warpAffine函数对图像img应用仿射变换。参数M是仿射变换矩阵,(cols,rows)是输出图像的尺寸。
dst = cv.warpAffine(img, M, (cols,rows))
cv.imshow('original', img)
cv.imshow('result', dst)
cv.waitKey(0)
cv.destroyAllWindows()

代码效果图:

4. 图像缩放

图像比例缩放是指将给定的图像在x轴方向按比例缩放x倍,在y轴方向按比例缩放y倍,从而获得一幅新图像。

在OpenCV中,实现图像缩放的函数是resize,函数声明如下:

resize(src,dsize[,dst[fx[,interpolation]]]]→dst

参数s表示原图像;

dst表示输出图像;

dsize表示目标图像大小;

fx表示在x轴上放缩比例;

fy表示在y轴上的放缩比例;

interpolation表示插值方式,

注意:dsize,fx和fy不能同时为零。

代码实例:实现图像的缩放

import numpy as np
import cv2

def resizeImage(image,width=None,height=None,inter=cv2.INTER_AREA):
    newsize = (width,height)  # 初始化新尺寸变量。
    #获取图像尺寸
    (h,w) = image.shape[:2]
    if width is None and height is None:
        return image
    #高度算缩放比例
    if width is None:
        n = height/float(h)
        newsize = (int(n*w),height)
    else :
        n = width/float(w)
        newsize = (width,int(h*n))
    # 使用cv2.resize函数根据计算出的newsize缩放图像。
    newimage = cv2.resize(image, newsize, interpolation=inter)
    return newimage

imageOriginal = cv2.imread("lakeWater.jpg")
cv2.imshow("Original", imageOriginal)
#获取图像尺寸
w = width=imageOriginal.shape[1]
h = width=imageOriginal.shape[0]
print ("Image size:",w,h)
#放大2倍
newimage = resizeImage(imageOriginal,w*2,h*2,cv2.INTER_LINEAR)
cv2.imshow("New", newimage)
#保存缩放后的图像
cv2.imwrite('newimage.jpg',newimage)
#缩小5倍
newimage2 = resizeImage(imageOriginal,int(w/5),int(h/5),cv2.INTER_LINEAR)
cv2.imwrite('newimage2.jpg',newimage2)
cv2.imshow('result', newimage)
cv2.waitKey(0)
cv2.destroyAllWindows()

参考学习书总结:OpenCv4.5 计算机视觉开发实战(基于python)

代码来自书本,供自己学习复习使用,继续学习ing...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

听说你还在搞什么原创~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值