工作总结
这几周时间,我们小组在原有项目的基础上实现了论文代码的部分复现,对眼动识别瞳孔检测的算法优化,UI界面的实现以及对虹膜,嘴,鼻子,眉毛,内嘴和下颌的轮廓检测。
实现效果如下:
图像处理
这里复现了论文的datasets部分,为了使检测点的模型具有更好的抗干扰能力和鲁棒性。使用论文提供的公共数据集(七万张图片),对图像进行了翻转,通道变换,随机添加噪声,亮度,对比度,饱和度,旋转,缩放等操作。
import numpy as np
import cv2
import sys
sys.path.append('..')
from torch.utils import data
from torch.utils.data import DataLoader
import os
import random
# annotation存放着的点
def flip(img, annotation):
# parse
# 图像矩阵左右翻转
img = np.fliplr(img).copy()
# 数组的前两个参数
h, w = img.shape[:2]
# 左闭右开
x_min, y_min, x_max, y_max = annotation[0:4]
# 从4开始读取,之间相差为2
landmark_x = annotation[4::2]
landmark_y = annotation[4+1::2]
bbox = np.array([w - x_max, y_min, w - x_min, y_max])
for i in range(len(landmark_x)):
landmark_x[i] = w - landmark_x[i]
new_annotation = list()
new_annotation.append(x_min)
new_annotation.append(y_min)
new_annotation.append(x_max)
new_annotation.append(y_max)
for i in range(len(landmark_x)):
new_annotation.append(landmark_x[i])
new_annotation.append(landmark_y[i])
return img, new_annotation
# 随机打乱图片的通道数
def channel_shuffle(img, annotation):
if img.shape[2] == 3:
ch_arr = [0, 1, 2]
np.random.shuffle(ch_arr)
img = img[..., ch_arr]
return img, annotation
#随机添加噪声
def random_noise(img, annotation, limit=[0, 0.2], p=0.5):
#随机生成0到1的浮点数,有0.5的概率产生噪声
if random.random() < p:
H, W = img.shape[:2]
# 从中随机采样
noise = np.random.uniform(limit[0], limit[1], size=(H,W)) * 255
# 增加新维度
img = img + noise[:,:,np.newaxis]*np.array([1,1,1])
#
img = np.clip(img, 0, 255).astype(np.uint8)
return img, annotation
# 将原图片的噪声随机变换为原来的0.7-1.3之间
def random_brightness(img, annotation, brightness=0.3):
alpha = 1 + np.random.uniform(-brightness, brightness)
img = alpha * img
img = np.clip(img, 0, 255).astype(np.uint8)
return img, annotation
# 对比度
def random_contrast(img, annotation, contrast=0.3):
coef = np.array([[[0.114, 0.587, 0.299]]])
alpha = 1.0 + np.random.uniform(-contrast, contrast)
gray = img * coef
gray = (3.0 * (1.0 - alpha) / gray.size) * np.sum(gray)
img = alpha*img+ gray
img = np.clip(img, 0, 255).astype(np.uint8)
return img, annotation
# 饱和度
def random_saturation(img, annotation, saturation=0.5):
coef = np.array([[[0.299, 0.587, 0.114]]])
alpha = np.random.uniform(-saturation, saturation)
gray = img * coef
gray = np.sum(gray,axis=2, keepdims=True)
img = alpha*img + (1.0 - alpha)*gray
img = np.clip(img, 0, 255).astype(np.uint8)
return img, annotation
# 色相
def random_hue(image, annotation, hue=0.5):
h = int(np.random.uniform(-hue, hue)*180)
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
hsv[:, :, 0] = (hsv[:, :, 0].astype(int) + h) % 180
image = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
return image, annotation
# 缩放
def scale(img, annotation):
f_xy = np.random.uniform(-0.4, 0.8)
origin_h, origin_w = img.shape[:2]
bbox = annotation[0:4]
landmark_x = annotation[4::2]
landmark_y = annotation[4+1::2]
h, w = int(origin_h * f_xy), int(origin_w * f_xy)
image = cv2.resize(img, (h, w)).astype(np.uint8)
new_annotation = list()
for i in range(len(bbox)):
bbox[i] = bbox[i] * f_xy
new_annotation.append(bbox[i])
for i in range(len(landmark_x)):
landmark_x[i] = landmark_x[i] * f_xy
landmark_y[i] = landmark_y[i] * f_xy
new_annotation.append(landmark_x[i])
new_annotation.append(landmark_y[i])
return image, new_annotation
def rotate(img, annotation, alpha=30):
bbox = annotation[0:4]
landmark_x = annotation[4::2]
landmark_y = annotation[4+1::2]
center = ((bbox[0] + bbox[2])/2, (bbox[1]+bbox[3])/2)
rot_mat = cv2.getRotationMatrix2D(center, alpha, 1)
img_rotated_by_alpha = cv2.warpAffine(img, rot_mat,(img.shape[1],img.shape[0]))
point_x = [bbox[0], bbox[2], bbox[0], bbox[2]]
point_y = [bbox[1], bbox[3], bbox[3], bbox[1]]
new_point_x = list()
new_point_y = list()
# 旋转矩阵乘坐标
for (x, y) in zip(landmark_x, landmark_y):
new_point_x.append(rot_mat[0][0] * x + rot_mat[0][1] * y + rot_mat[0][2])
new_point_y.append(rot_mat[1][0] * x + rot_mat[1][1] * y + rot_mat[1][2])
new_annotation = list()
new_annotation.append(min(new_point_x))
new_annotation.append(min(new_point_y))
new_annotation.append(max(new_point_x))
new_annotation.append(max(new_point_y))
for (x, y) in zip(landmark_x, landmark_y):
new_annotation.append(rot_mat[0][0] * x + rot_mat[0][1] * y + rot_mat[0][2])
new_annotation.append(rot_mat[1][0] * x + rot_mat[1][1] * y + rot_mat[1][2])
return img_rotated_by_alpha, new_annotation