一、图像的基本处理--运算
以下所有函数均省略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。
- 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()
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)
这就是图像几何变换的大部分内容了。