Opencv入门系列四

Opencv入门系列四


主要内容

  • 缩放
  • 翻转
  • 仿射变换
  • 透视
  • 重映射

1.缩放

cv2.resize()函数用于实现图像的缩放,其语法如下:

image-20210201120438932

● dst:缩放后的图像,

​ 图像的类型与src相同,

​ 图像的大小为dsize 或者 可以通过src.size()、fx、fy计算得到。

● src:缩放的原图像。

● dsize:输出图像大小。

● fx:水平方向的缩放比例。

● fy:垂直方向的缩放比例。

● interpolation代表插值方式

关于缩放尺寸的参数传入方式:

​ 方式一:通过fx,fy

  • fx:表示x方向的缩放比例

  • fy:表示y方向的缩放比例

    方式二:通过dsize

    注意:从img.shape[0:2]获取的参数为[行,列]

    传入的 dsize = [列,行]

    如下程序:

    import cv2
    import numpy as np
    #按照原比例缩放需要注意,行列参数顺序
    
    # 从原始图像获取图像大小信息
    npImg = np.random.randint(0,255,[4,3,3],dtype=np.uint8)
    Rows,Clos = OriShape = npImg.shape[0:2]     # OriShape =  (4, 3)
    ChangeImg = cv2.resize(npImg,OriShape)
    NewShape = ChangeImg.shape[0:2]             # NewShape =  (3, 4)
    Size = (int(Rows*0.9),int(Clos*0.5))
    ChangeImg2 = cv2.resize(npImg,Size)
    NewShape2 = ChangeImg2.shape[0:2]
    ChangeImg3 = cv2.resize(npImg,None,fx=Rows,fy=Clos) #fx x的增缩比例 fy y的增缩比例
    NewShape3 = ChangeImg3.shape[0:2]
    
    print(npImg)
    print(ChangeImg)
    print(ChangeImg2)
    print(ChangeImg3)
    
    print("OriShape = ",OriShape)
    print("\n")
    print("NewShape = ",NewShape)
    print("\n")
    print("Size",Size)
    print("\n")
    print("NewShape3",NewShape3)
    

    image-20210201134502688

    从图中的转换的前后的shape信息可以看出其性质。

    ● 在shape属性中,第1个值对应的是行数,第2个值对应的是列数。

    ● 在dsize参数中,第1个值对应的是列数,第2个值对应的是行数。

关于插值方式:

插值:插值指的是

​ ①:在放大时,有部分点无法得到对应的映射,需要填充像素点。

​ ②:在缩小时,有部分像素点是非整数索引位置,此时也需要插值处理。

Opencv库提供了一系列的插值方式如下表:

image-20210201121100985

Opencv中默认使用双线性插值方式。

​ 在缩小图像时,使用区域插值方式(INTER_AREA)能够得到最好的效果。

​ 在放大图像时,使用三次样条插值(INTER_CUBIC)方式和双线性插值(INTER_LINEAR)方式都能够取得较好的效果。

2.翻转

cv2.flip()用于图像的水平,垂直方向,其语法如下:

image-20210201135238069

● dst代表和原始图像具有同样大小、类型的目标图像。

● src代表要处理的原始图像。

● flipCode代表旋转类型。

flipCode旋转类型如下:

image-20210201135350397

3.仿射

仿射:变换保持原有的平直性和平行性,用于实现放射可以完成平移、旋转等多种操作。

3.1 平移

cv2.warpAffine()其语法如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jMl7e5lO-1612163236890)(C:\Users\44338\AppData\Roaming\Typora\typora-user-images\image-20210201135943897.png)]

● dst:仿射后的输出图像,该图像的类型和原始图像的类型相同。dsize决定输出图像的实际大小。

● src:要仿射的原始图像。

● M:一个2×3的变换矩阵。使用不同的变换矩阵,就可以实现不同的仿射变换。

● dsize:输出图像的尺寸大小。

● flags:插值方法,默认为INTER_LINEAR。当该值为WARP_INVERSE_MAP时,意味着M是逆变换类型,实现从目标图像dst到原始图像src的逆变换。

● borderMode:边类型,默认为BORDER_CONSTANT。当该值为BORDER_TRANSPARENT时,意味着目标图像内的值不做改变,这些值对应原始图像内的异常值。

● borderValue:边界值,默认是0。

一般情况下,falgs、borderMode、borderValue等参数可以省略,使用默认值

仿射后的矩阵与原始矩阵关系如下式:

image-20210201140326659

M13、M23:通常用于平移操作

M11、M12、M21、M22:通常御用图像的变换

下列程序是一个平移的实例:

import cv2
import numpy as np


lena = cv2.imread("Resources/lena.png",1)
cv2.imshow("lena",lena)
Width,High = lena.shape[0:2]

x = 100
y = 200
M = np.float32([[1,0,x],[0,1,y]]) #M参数是一个np中float32类型的矩阵

wrapLena = cv2.warpAffine(lena,M,dsize=(Width,High))
cv2.imshow("warpLena",wrapLena)
cv2.waitKey(0)

image-20210201141245659

3.2 旋转

cv2.getRotationMatrix2D()获取转换矩阵,用于cv2.warpAffine()中的参数M中。其语法如下:

image-20210201141738804

● center为旋转的中心点。

● angle为旋转角度,正数表示逆时针旋转,负数表示顺时针旋转。

● scale为变换尺度(缩放大小)。

import cv2
import numpy as np


lena = cv2.imread("Resources/lena.png",1)
cv2.imshow("lena",lena)
Width,High = lena.shape[0:2]

RotationCenter = (Width/2,High/2)

#M_Rotation为以原图中心为旋转中心,旋转角度45度,缩小到原来的图像
M_Rotation = cv2.getRotationMatrix2D(RotationCenter,45,0.5)

wrapLena2 = cv2.warpAffine(lena,M_Rotation,dsize=(Width,High))
cv2.imshow("warpLena2",wrapLena2)
cv2.waitKey(0)

3.3 复杂的仿射

OpenCV提供了函数cv2.getAffineTransform()来生成仿射函数cv2.warpAffine()所使用的转换矩阵M。该函数的语法格式为:

image-20210201142513704

● src代表输入图像的三个点坐标。

● dst代表输出图像的三个点坐标。

其参数值src和dst是包含三个二维数组(x, y)点的数组

import cv2
import numpy as np


lena = cv2.imread("Resources/lena.png",1)
cv2.imshow("lena",lena)
Width,High = lena.shape[0:2]

ArrayOri = np.float32([[0,0],[Width-1,0],[0,High-1]])
ArrayNew = np.float32([[0,0],[Width*0.5,0],[0,High*0.5]])

M = cv2.getAffineTransform(ArrayOri,ArrayNew)

wrapLena2 = cv2.warpAffine(lena,M,dsize=(Width,High))
cv2.imshow("warpLena2",wrapLena2)
cv2.waitKey(0)

image-20210201143409669

4. 透视

透视:将矩形映射为任意平行四边形,透视变换则可以将矩形映射为任意四边形,cv2.warpPerspective()实现透视,其语法是:

image-20210201143510174

● dst:透视处理后的输出图像,该图像和原始图像具有相同的类型。dsize决定输出图像的实际大小。

● src:要透视的图像。

● M:一个3×3的变换矩阵。

● dsize:输出图像的尺寸大小。

● flags:插值方法,默认为INTER_LINEAR。当该值为WARP_INVERSE_MAP时,意味着M是逆变换类型,能实现从目标图像dst到原始图像src的逆变换。具体可选值参见表5-1。

● borderMode:边类型,默认为BORDER_CONSTANT。当该值为BORDER_TRANSPARENT时,意味着目标图像内的值不做改变,这些值对应原始图像内的异常值。

● borderValue:边界值,默认是0。

我们可以通过函数cv2.getPerspectiveTransform()来生成函数cv2.warpPerspective()所使用的转换矩阵M:其语法格式如下

image-20210201143808482

● src:输入图像的四个顶点的坐标。

● dst:输出图像的四个顶点的坐标。

5. 重映射

重映射:值将一幅图的像素点的任何位置放到另一幅图像的操作。Opencv库中提供了很多方法实现重映射操作,比如cv2.remap(),其语法格式如下:

image-20210201144232040

● dst代表目标图像,它和src具有相同的大小和类型。

● src代表原始图像。

● map1参数有两种可能的值:

​ - 表示(x, y)点的一个映射。

​ - 表示CV_16SC2 , CV_32FC1, CV_32FC2类型(x, y)点的x值。

● map2参数同样有两种可能的值:

​ - 当map1表示(x, y)时,该值为空。

​ - 当map1表示(x, y)点的x值时,该值是CV_16UC1,CV_32FC1类型(x, y)点的y值。

● Interpolation代表插值方式,这里不支持INTER_AREA方法。具体值参见表5-1。

● borderMode代表边界模式。当该值为BORDER_TRANSPARENT时,表示目标图像内的对应源图像内奇异点(outliers)的像素不会被修改。

● borderValue代表边界值,该值默认为0。

注意:

①:map1和map2的值都是浮点数。所以需要插值方式提供安全操作。

②:参数map1指代的是像素点所在位置的列号,参数map2指代的是像素点所在位置的行号

下面程序实现了图像的复制和进行x,y镜像

import cv2
import numpy as np

Newnp = np.random.randint(0,100,[3,3],dtype=np.uint8)
rows,clos = Newnp.shape[0:2]

# 必须保证类型为float32
np_x = np.float32(np.ones([3,3],dtype=np.uint8)*2)
np_y = np.float32(np.ones([3,3],dtype=np.uint8)*1)

for i in range(rows):
    for j in range(clos):
        #np_x[i,j] = j
        #np_y[i,j] = i
        np_x.itemset((i,j),j)
        np_y.itemset((i,j),i)
CopyImg = cv2.remap(Newnp,np_x,np_y,cv2.INTER_LINEAR)

for i in range(rows):
    for j in range(clos):
        #np_x[i,j] = j
        #np_y[i,j] = i
        np_x.itemset((i,j),i)
        np_y.itemset((i,j),j)
TurnImg = cv2.remap(Newnp,np_x,np_y,cv2.INTER_LINEAR)

print(Newnp)
print(CopyImg)
print(TurnImg)



#print(np2)cv2.imshow("warpLena2",wrapLena2)
cv2.waitKey(0)

不难看出我们还可以使用remap()方法实现x轴镜像,y轴镜像,以及一些更复杂的操作。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值