一、图像的基本处理--运算

以下所有函数均省略cv2.。

1.1.1加法运算

之前已经说过,对于计算机而言,图像不过只是矩阵罢了。

图像的相加,也就是矩阵相加。

我们使用add(a, b)函数来实现图像的加法运算。

注意:当a+b<=255时,a+b = a+b;当a+b>255时,a+b = 255。

它们的和加起来如果超过255,会被截断。

Dst = add(image1,image2) #即Dst为两幅图像相加的结果

Dst = add(image1,6) #即Dst为image1矩阵中每个值加上6后的值

1.1.2减法运算

我们使用subtract(a, b)函数来实现图像的减法运算。

注意:当a-b>=0时,a-b = a-b;当a-b<0时,a-b = 0。

  1. b)的差值如果小于0,会被截断。

例:1-6 = 0; 5 -6 = 0。

该函数使用方法同上(加法运算)。

1.1.3乘法运算

矩阵乘法有两种,一种是纯数学的矩阵相乘,还有一种是矩阵点乘

第一种我们用可以用numpy模块中的dot(a, b)来得到。

调用方法为:dst = numpy.dot(a, b)

第二种为矩阵点乘,实现它的函数在opencv模块中有,为multiply(a, b)。{省略cv2.}

调用方法和上面一样。

并且它在乘积大于255时,会和加法运算一样,截断在255处。

Dst = multiply(a, b)

1.1.4除法运算

我们使用divide(a, b)函数来实现图像的除法运算。

注意:除法后得到的最终结果都是整数,因为像素的范围在0~255之间且为整数。

它使用的是四舍五入发来近似。

Dst = divide(a, b)

1.1.5按位与

我们使用bitwise_and(src1. src2)来实现图像的按位与运算。

图像也就是矩阵,该函数本质上就是将两个矩阵的每个值划成了8为2进制数,在进行按位与运算。

src1是矩阵1,src2是矩阵2。

调用方法:

Dst = bitwise_and(src1, src2) #Dst为src1和src2按位与运算后的结果矩阵

1.1.6按位或

我们使用bitwise_or(src1. src2)来实现图像的按位或运算。

按位或运算和按位与运算差不多。

调用方法:

Dst = bitwise_or(src1, src2) #Dst为src1和src2按位或运算后的结果矩阵

1.1.7按位非

我们使用bitwise_not(src1)来实现图像的按位非运算。

调用方法:

Dst = bitwise_not(src1) #Dst为src1按位非运算后的结果矩阵

一般用在黑白图像中。

1.1.8按位异或

我们使用bitwise_xor(src1. src2)来实现图像的按位异或运算。

调用方法:

Dst = bitwise_xor(src1, src2) #Dst为src1和src2按位异或运算后的结果矩阵

二、图像的几何变换

2.1仿射变换

仿射变换是指图像可以通过一系列变换来实现平移、缩放、旋转等操作。

Opencv模块提供的仿射变换用的函数为warpAffine()。

仿射变换需要一个映射矩阵M,该矩阵大小为2x3。

该函数调用方法:

Dst = warpAffine(src, M, dsize)

src是原始图像。

M是映射矩阵。

dsize表示输出图像的尺寸大小。

Dst是输出图像(也就是仿射变换后的图像)

2.1.1平移和缩放

对于平移和缩放,它们的实质是一样的,只需要改变映射矩阵M即可。

M = np.array([0.8, 0, 120;

                        0, 0.5, 20])

该映射矩阵表示图片横向变为原来的0.8倍,纵向变为原来的0.5倍,向右平移120个单位,向下平移20个单位。

简单来说就是这样。

调用时先获取图片的纵向长度和横向长度

h,w = image.shape[0:2]

在创建映射矩阵M

import numpy as np

M = np.float32([[1,0,120], [0,1,20]])

再使用仿射函数

image_Move = cv.warpAffine(image, M, (w,h))

这样得到的image_Move就是经过平移和缩放后的图片了。

下面一段代码显示两张处理后的图片,一张是平移的,一张是缩小的。

import cv2 as cv
import numpy as np

image = cv.imread("E:/dahai.jpeg")

h, w = image.shape[0:2]
print(h)    # 纵向距离
print(w)    # 横向距离
M = np.float32([[1,0,120], [0,1,20]]) #向右120,下20,平移

image_Move = cv.warpAffine(image, M, (w,h))

cv.imshow("image",image)
cv.imshow("image_move",image_Move)

M2 = np.float32([[0.8, 0, 0], [0, 0.5, 0]]) # 横向为原来的0.8倍,纵向为原来的0.5倍
image_Suo = cv.warpAffine(image, M2, (w,h)) # 缩小一倍
cv.imshow("image_Suo", image_Suo)

cv.waitKey()
cv.destroyAllWindows()

2.1.2旋转

当想要对图片进行旋转操作时,映射矩阵就不好认为给出,这里我们可以使用opencv模块中提供的getRotationMatrix2D()函数来得到让图像旋转所需的映射矩阵。

调用方法:

M = getRotationMatrix2D(center, angle, scale)

center是旋转的中心点

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

scale表示变换尺度,输出图像大小变为原始图像的scale倍

调用方法和之前一样,只是换了一下映射矩阵M的得出方式。

使用的话,依旧是老样子。

先得映射矩阵,

然后进行仿射变换,

再显示图像(记得延时)即可。

例:

import cv2 as cv

image = cv.imread("E:/dahai.jpeg")
h,w = image.shape[0:2]   # h是竖向长度,w是横向长度
print(image.shape)
print(h)
print(w)
# w1,h1 = image.shape[:2-图像的几何变化]
# print(w1)
# print(h1)

M = cv.getRotationMatrix2D((w/2,h/2), 30, 0.6)
#创建了一个以(w/2-图像的几何变化,h/2-图像的几何变化)为中心,逆时针旋转10°,大小为原图的0.8倍的仿射矩阵

image_Xuan = cv.warpAffine(image, M, (w,h))

cv.imshow("image_Xuan",image_Xuan)
cv.imwrite("E:/xuanzhuang.jpeg",image_Xuan)
cv.waitKey()
cv.destroyAllWindows()

    

怎么让一个图减去另一种图用python实现 python两张图片相减_python

 

2.2重映射

将一副图像内的像素点放置到另一幅图像的指定位置,这个操作过程叫做重映射。

重映射通过修改像素点的位置得到一副新图像。

映射函数的作用就是查找新图像像素再原始图像内的位置。

Opencv中的remap()函数可用于我们的自定义重映射。

调用方法:

Dst = remap(src, map1, map2, interpolation)

src表示原始图像

map1表示点(x,y)的x值

map2表示点(x,y)的y值

interpolation表示插值方式,一般我们填cv2.INTER_LINEAR即可

简单来说,

重映射就是先读取图像的数据,形成矩阵。

然后创建和图像矩阵尺寸大小相同的两个矩阵(X和Y)。

再依次对图像矩阵和X,Y矩阵遍历,将图像矩阵的信息按一定规律放入X,Y矩阵中。

再使用重映射函数Dst = remap(image, X, Y, cv2.INTER_LINEAR)

Dst就是映射后的图像矩阵。

2.2.1复制

import cv2 as cv
import numpy as np

image = cv.imread("E:/dahai.jpeg")
h,w = image.shape[0:2]   #h是纵向距离,w是横向距离
print(h,w,sep=',')#查看纵横向距离大小
#下面两行创建大小为(h,w)的0矩阵
x = np.zeros((h,w), np.float32)
y = np.zeros((h,w), np.float32)

for i in range(h):#i表示纵向,j表示横向
    for j in range(w):
        x.itemset((i,j), j)
        y.itemset((i,j), i)

rst = cv.remap(image, x, y, cv.INTER_LINEAR)
cv.imshow("rst",rst)
cv.imshow("image",image)
cv.imwrite("E:/pycharm/dahai-xy.jpeg",rst)
cv.waitKey()
cv.destroyAllWindows()

2.2.2翻转

翻转的话,只需要改变以上的遍历部分。

绕y轴翻转:

import cv2 as cv
import numpy as np

image = cv.imread("E:/dahai.jpeg")
h,w = image.shape[0:2]   #h是纵向距离,w是横向距离
print(h,w,sep=',')#查看纵横向距离大小
#下面两行创建大小为(h,w)的0矩阵
x = np.zeros((h,w), np.float32)
y = np.zeros((h,w), np.float32)

for i in range(h):#i表示纵向,j表示横向
    for j in range(w):
        x.itemset((i,j), w-1-j)    # 绕y轴翻转
        y.itemset((i,j), i)

rst = cv.remap(image, x, y, cv.INTER_LINEAR)
cv.imshow("rst",rst)
cv.imshow("image",image)
cv.imwrite("E:/pycharm/dahai-xy.jpeg",rst)
cv.waitKey()
cv.destroyAllWindows()

绕x轴翻转:(末尾略过)

import cv2 as cv
import numpy as np

image = cv.imread("E:/dahai.jpeg")
h,w = image.shape[0:2]   #h是纵向距离,w是横向距离
print(h,w,sep=',')#查看纵横向距离大小
#下面两行创建大小为(h,w)的0矩阵
x = np.zeros((h,w), np.float32)
y = np.zeros((h,w), np.float32)

for i in range(h):#i表示纵向,j表示横向
    for j in range(w):
        x.itemset((i,j), j)
        y.itemset((i,j), h-1-i)

绕x和y轴都翻转:

import cv2 as cv
import numpy as np

image = cv.imread("E:/dahai.jpeg")
h,w = image.shape[0:2]   #h是纵向距离,w是横向距离
print(h,w,sep=',')#查看纵横向距离大小
#下面两行创建大小为(h,w)的0矩阵
x = np.zeros((h,w), np.float32)
y = np.zeros((h,w), np.float32)

for i in range(h):#i表示纵向,j表示横向
    for j in range(w):
        x.itemset((i,j), w-1-j)
        y.itemset((i,j), h-1-i)

这就是图像几何变换的大部分内容了。