因身体状况欠佳,可能会暂缓更新。
之前我们提到了CNN过拟合问题,面对过拟合我们一般有两种方法来处理,第一种方法则是扩充数据集。
在数据集给定的情况下,我们则不得不用已有图片,经过处理来扩充我们的数据集。
我们这里以第一张猫为例来介绍下cv2的基本用法:
import cv2
img = cv2.imread('./dataset/cats_and_dogs_filtered/train/cats/cat.0.jpg', 1)
cv2.imshow('cat', img) #第一个参数为图片名称,第二个参数为我们输入的矩阵
cv2.waitKey(0) #0为不限时间,接收到键盘指令才会继续。也可以输入正整数,单位为毫秒。
# 例如 cv2.waitKey(5000) 5000毫秒后会运行cv2.destroyAllWindows() 在5000毫秒期间你仍然可以# 通过任意键来继续
cv2.destroyAllWindows() #关闭我们所有的窗口
cv2.imread(),返回的是个数组ndarray(dtype=uint8),其中数值我们也可以更改。
imread第二个参数有多种方式让我们读取:
cv2.IMREAD_COLOR (默认读取方式,也可以用1来代替): 读取彩色图片,不包括alpha值(透明度)
cv2.IMREAD_GRAYSCALE (也可以用0来代替): 图像灰度处理,这样压缩了了图片尺寸,但也会丢失特征。
cv2.IMREAD_UNCHANGED (也可以用-1来代替): 读取彩色图片,且包括alpha值(透明度)
cv2.imshow(name,img) 的窗口大小会自动拟合图片尺寸。
在这里我们看到的窗口是不可改变大小的,下面我们将用其他方法来改变窗口大小:
img = cv2.imread('./dataset/cats_and_dogs_filtered/train/cats/cat.0.jpg', 1)
cv2.namedWindow('cat', cv2.WINDOW_NORMAL)
cv2.imshow('cat', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
这里nameWindow 的name 需要和imshow的一致。
这时我们发现我们的窗口已经可以更改大小了。
图片的储存也是非常简单:
img = cv2.imread('./dataset/cats_and_dogs_filtered/train/cats/cat.0.jpg', 1)
cv2.imwrite('cat0.png', img)
我们也可以通过键入不同的key来执行不同的操作:
img = cv2.imread('./dataset/cats_and_dogs_filtered/train/cats/cat.0.jpg', 1)
cv2.imshow('image', img)
k = cv2.waitKey(0) & 0xFF
if k == 27: # wait for ESC key to exit
cv2.destroyAllWindows()
elif k == ord('s'): # wait for 's' key to save and exit
cv2.imwrite('cat0.png',img)
cv2.destroyAllWindows()
32位系统只需 k = cv2.waitKey(0) 64位需要 k=cv2.waitKey(0) & 0xFF 来保证补码的一致性.(可以不用理解)
对于cv2.imread读取的图像也可以通过plt.imshow()来显示。
cv2还有很多其他有用的功能,不过今天我们需要的是图片的几何变换,因此其他的内容暂时可以不看。
首先是图片resize:
img = cv2.imread('./dataset/cats_and_dogs_filtered/train/cats/cat.0.jpg', 1)
res = cv2.resize(img, (150, 150), interpolation=cv2.INTER_CUBIC)
cv2.imshow('cat_resize', res)
cv2.waitKey(0)
cv2.destroyAllWindows()
如果我们没有目标尺寸,只是想让图片缩放,比如缩放为1/4(长宽各缩放1/2)。那么就可以这么改写
res = cv2.resize(img, None, fx=1/2, fy=1/2, interpolation=cv2.INTER_CUBIC)
这里的fx fy 代表横纵轴比例,可以小于1也可以大于1。
关于interpolation 有几个参数可以选择:
cv2.INTER_AREA - 局部像素重采样,适合缩小图片。
cv2.INTER_CUBIC和 cv2.INTER_LINEAR 更适合放大图像,其中INTER_LINEAR为默认方法。
图像平移:
img = cv2.imread('./dataset/cats_and_dogs_filtered/train/cats/cat.0.jpg', 1)
rows, cols = img.shape[0:2]
M = np.float32([[1, 0, 100], [0, 1, 50]])
dst = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow('img', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
这里M是构建一个矩阵 ,该例子中,为沿x轴移动100像素,y轴移动50 原点(0,0)在左上角)。
cv2.warpAffine()的第三个参数是输出图片的大小,输入为(宽度,高度) 宽度为cols 高度为rows。
旋转:
但是opencv提供了另一种方法让我们可以改变旋转中心。
为了得到这个旋转矩阵,opencv提供了一个函数:
cv2.getRotationMatrix2D 。 该函数需要3个参数, 旋转中心,旋转角度,缩放比例。
img = cv2.imread('./dataset/cats_and_dogs_filtered/train/cats/cat.0.jpg', 1)
rows, cols = img.shape[0:2]
M = cv2.getRotationMatrix2D((cols/2, rows/2), 90, 1)
dst = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow('img', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
图片的仿射变换:
opencv提供了getAffineTransform函数来进行仿射变换,该函数有2个参数需要输入,第一个为原图像的三个点,第二个为原图像该3个点在新图像中的位置。M为仿射变换矩阵。
import cv2
import numpy as np
img = cv2.imread('./dataset/cats_and_dogs_filtered/train/cats/cat.0.jpg', 1)
rows, cols = img.shape[0:2]
pts1 = np.float32([[50, 50], [200, 50], [50, 200]])
pts2 = np.float32([[10, 100], [200, 50], [100, 250]])
M = cv2.getAffineTransform(pts1,pts2)
dst = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow('img', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
图像的透视变换:
透视变换则是将图像投影到一个新的平面:
这里我们依旧用点对点的方式来找。这里用的函数则是cv2.getPerspectiveTransform()
需要注意的是这回我们得到的矩阵是3x3的,之前warpAffine接收到的矩阵为2x3的,这里我们需要
warpPerspective来得到新的图像。
import cv2
import numpy as np
img = cv2.imread('./dataset/cats_and_dogs_filtered/train/cats/cat.0.jpg', 1)
rows, cols, ch = img.shape
pts1 = np.float32([[124,11],[371,11],[124,255],[371,255]])
pts2 = np.float32([[0,0],[150,0],[0,150],[150,150]])
M = cv2.getPerspectiveTransform(pts1, pts2)
dst = cv2.warpPerspective(img, M, (150, 150))
cv2.imshow('img', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
以上内容来自 官方教程 ,图片用的我们之前训练集的例子。英文阅读无障碍的建议看一下官方教程。
下一次我们将会用我们新学的方法来扩充我们的训练集。