OpenCV扩大图像数据库
由于无论使用何种算法和框架对神经网络进行训练,图片的数据量始终是一个决定训练模型好坏的重要前提。数据扩展是训练模型的一个常用手段,对于模型的鲁棒性以及准确率都有非常重要的帮助。
1 图像的随机裁剪
图片的随机裁剪是一个常用的扩大图像数据库的手段,好处是对于大多数的图片数据,进行模型之前都需变成统一的大小。虽图片的大小相同,但不同的裁剪位置却能够提供更多的数据样本,从而提高基本的图片数据的内容。
import cv2
import numpy as np
import random
import matplotlib.pyplot as plt
img = cv2.imread("leaf.png")
width, height, depth = img.shape
img_width_box = width * 0.7
img_heigth_box = height * 0.7
# 截取的图片个数
for _ in range(10):
# 均匀分布随机数
start_pointX = np.int(random.uniform(0, img_width_box))
start_pointY = np.int(random.uniform(0, img_heigth_box))
copyImg = img[start_pointX:300, start_pointY:300]
copyImg = cv2.resize(copyImg, (100, 100))
cv2.imwrite("pic/"+"2_"+str(_)+".jpg", copyImg)
2 图像的随机旋转变换
相对于图像的旋转、平移和翻转(wrapAffine(): 仿射变换),图像的随机旋转变换并不会使得图片变形。
cv2.getRotationMatrix2D(center, angle, scale): 计算2D旋转的仿射矩阵
参数:
center: 旋转的中心
angle: 旋转的角度
scale: 缩放的倍数
【 问题:黑边的去除(未完成)】
import cv2
import numpy as np
from scipy import ndimage
img = cv2.imread("leaf.png")
width, height, depth = img.shape
# 计算仿射矩阵
img_change = cv2.getRotationMatrix2D((width/2, height/2), 45, 1)
# 仿射变换
res = cv2.warpAffine(img, img_change, (width, height))
cv2.imshow("res", res)
cv2.waitKey()
3 图像色彩的随机变换
import cv2
import numpy as np
import random
img = cv2.imread("leaf.png")
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 产生10张图片
for i in range(10):
# H范围:[0, 180]
# S范围:[0, 255]
# V范围:[0, 255]
turn_green_hsv = img_hsv.copy()
turn_green_hsv[:, :, 0] = (turn_green_hsv[:, :, 0] + np.random.randint(1, 180)) % 180
turn_green_hsv[:, :, 1] = (turn_green_hsv[:, :, 1] + np.random.randint(1, 255)) % 255
turn_green_hsv[:, :, 2] = (turn_green_hsv[:, :, 2] + np.random.randint(1, 255)) % 255
turn_green_img = cv2.cvtColor(turn_green_hsv, cv2.COLOR_HSV2BGR)
turn_green_img = cv2.resize(turn_green_img, (100, 100))
cv2.imwrite("pic/"+"12_"+str(i)+".jpg", turn_green_img)
4 对鼠标的监控
使用鼠标在生成的图片上标记出目标位置是基本的数据处理内容。鼠标操作输入用户接口操作,OpenCV同样提供了对鼠标操作的函数,这一部分功能主要由mouse_event完成。mouse_event的功能是监控鼠标的操作,对鼠标的点击、移动、放开等作出反应,根据不同的操作进行处理。
事件共如下12种:
EVENT_LBUTTONDBLCLK = 7 # 左键双击
EVENT_LBUTTONDOWN = 1 # 左键单击
EVENT_LBUTTONUP = 4 # 左键释放
EVENT_MBUTTONDBLCLK = 9 # 中间双击
EVENT_MBUTTONDOWN = 3 # 中间点击
EVENT_MBUTTONUP = 6 # 中间释放
EVENT_MOUSEHWHEEL = 11 # 鼠标滚轮释放
EVENT_MOUSEMOVE = 0 # 鼠标移动
EVENT_MOUSEWHEEL = 10 # 鼠标滚轮
EVENT_RBUTTONDBLCLK = 8 # 右键双击
EVENT_RBUTTONDOWN = 2 # 右键点击
EVENT_RBUTTONUP = 5 # 右键释放
import cv2
import numpy as np
# 标志位:判断鼠标是否按下
drawing = False
ix, iy = -1, -1
rect_start = (0, 0)
# 创建回调函数
def on_mouse(event, x, y, flags, param):
global drawing
global ix, iy
global rect_start
# 当按下左键:返回起始坐标位置
if event == cv2.EVENT_LBUTTONDOWN:
drawing = True
# ix, iy = x, y
rect_start = (x, y)
# 鼠标左键按下并移动:绘制图形
# event: 判断鼠标是否移动
# flags: 判断是否是左键按下
elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:
if drawing == True:
# rectangle: (img, pt1, pt2, color, thickness=None, lineType=None, shift=None)
# img: image
# pt1: start point
# pt2: end point
# color: 三原色
# thickness: 构成矩阵的线条的粗细
# lineType: 线条类型
# shift: 点坐标中小数的位数
cv2.rectangle(img, rect_start, (x, y), (0, 0, 0), -1)
elif event == cv2.EVENT_LBUTTONUP:
drawing = False
# 创建图像与窗口,并将窗口与回调函数绑定
img = cv2.imread("leaf.png")
cv2.namedWindow("image")
cv2.setMouseCallback("image", on_mouse)
while True:
cv2.imshow("image", img)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cv2.destroyAllWindows()