1.读取人脸部图片
引入需要的库,并读取人脸的图片
import cv2
import matplotlib.pyplot as plt
import numpy as np
# 定义t2s函数,方便查看是否对图片进行RGB通道转换
def t2s(img):
return cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 读取图片
img = cv2.imread(r"d:\Users\1\week1_homework.png")
plt.figure(figsize=(5, 5))
plt.imshow(t2s(img))
plt.show()
2.对人脸进行平均滤波
首先需要设定kernel的值,卷积核越大,图像越模糊,但滤波效果会更好
# kernel 为均值滤波,使用该方法滤波核越大,图像越模糊,但滤波效果越好
kernel = np.ones((13, 13), np.float32) / (13*13) # (13, 13) 为卷积核的大小
# 将卷积应用于图像中
result = cv2.filter2D(img, -1, kernel)
plt.figure(figsize=(20, 20))
plt.imshow(t2s(cv2.hconcat([img, result]))) # 将img,result两个图片水平拼接
plt.show()
在进行均值滤波时,可以通过修改kernel的形态改变检验的重点方向,当重点检验x轴方向的边缘时,可以将kernel设置为:
# x方向上的kernel
kernel = np.ones((3, 3), np.float32) / (3*3)
kernel[0, :] = [-1, -1, -1]
kernel[1, :] = [0, 0, 0]
kernel[2, :] = [1, 1, 1]
当重点检验y轴方向的边缘时,kernel设置为:
# y方向上的kernel
kernel = np.ones((3, 3), np.float32) / (3*3)
kernel[0, :] = [-1, 0, 1]
kernel[1, :] = [-1, 0, 1]
kernel[2, :] = [-1, 0, 1]
![x轴方向边缘检测结果与原图对比](https://i-blog.csdnimg.cn/blog_migrate/943cd9b10304cb67b0fb97f6d1a57307.png)
![y轴方向边缘检测结果与原图对比](https://i-blog.csdnimg.cn/blog_migrate/9af1e6b6383811c1bc727b68134c7ffa.png)
在进行卷积操作时,可以通过观察运算前后矩阵的形态和矩阵中某个位置值的大小检查是否存在错误,如:
# 打印原始图片的大小
print(img.shape)
# 打印进行卷积后图像的大小
print(result.shape)
# 检查卷积后某一个像素点的值
px = 100
py = 200
print(result[px, py])
3.添加了肤色检测的人脸滤波
为更好识别人脸的区域,并改善平均滤波带来的图像模糊问题,增加了肤色检测,以方便对人脸区域内的肤色进行识别调整。
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread(r"d:\Users\WYN\Desktop\temp\1\week1_homework.png")
kernel = np.ones((21, 21), np.float32) / (21*21)
result = cv2.filter2D(img, -1, kernel)
#肤色检测
result_show = result.copy()
# 来源 https://www.cnblogs.com/demodashi/p/9437559.html
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 把图像转换到HSV色域
(_h, _s, _v) = cv2.split(hsv) # 图像分隔,分别获取h,s,v通道分量图像
skin3 = np.zeros(_h.shape, dtype=np.uint8) # 根据源图像的大小创建一个全0的矩阵,用于保存图像数据
(x, y) = _h.shape # 获取源图像数据的长和宽
# 遍历图像, 判断HSV通道的数值, 如果在指定范围中, 则置把新图像的点设为255,否则设为0
for i in range(0, x):
for j in range(0, y):
if (_h[i][j] > 7) and (_h[i][j] < 20) and (_s[i][j] > 28) and (_s[i][j] < 255) and (_v[i][j] > 50) and (_v[i][j] < 255):
skin3[i][j] = 255
else:
skin3[i][j] = 0
result_show[i][j] = img[i][j]
通过skin3我可以绘制出该算法识别的人脸区域
# 查验肤色检测区域
plt.imshow(t2s(skin3))
plt.show()
![](https://i-blog.csdnimg.cn/blog_migrate/376500aae4399e9c19c93b79cfb73923.png)
通过对人脸区域的HSV进行调整,得到修正后的图像
plt.figure(figsize=(20, 20))
plt.imshow(t2s(cv2.hconcat([img, result_show, result]))) # 将原图|肤色检测修正图|平均滤波修正图进行对比
plt.show()
![](https://i-blog.csdnimg.cn/blog_migrate/8807656b0c6fa3e9eb4be7e45a59a24b.png)
由此可以看出添加肤色检测算法后,会对检测出的皮肤区域进行修整,修整效果明显好于平均滤波的修整方法,但检测到的图像边缘界线并不明晰,该方法还有一定提升空间,后期可以考虑使用深度学习的方法,对任务面部标记参照点,已进行更好的识别。
参考链接:
Python人体肤色检测https://www.cnblogs.com/demodashi/p/9437559.html