1、计算机在检测人脸的过程中实际上是做分类检测,即发现图片中一些像素组成了:“眼睛特征”、“鼻子特征”等。
2、如果“眼睛特征”旁边有“鼻子特征”,“鼻子特征”旁边又有“眼睛特征”,着三个元素所在的区域就很有可能就是人脸区域;如果缺少了必要的特征,那么就不组成人脸的特征,就不是人脸了。
3、检测人脸的算法比较复杂,OpenCV将一系列算法封装好。一系列的简单分类器按照一定顺序级联到一起就构成了级联分类器。级联分类器的程序可以通过一系列简单的判断对样本进行识别。例如,依次满足“有羽毛”,“翅膀”,“鸟喙”,就可以。
OpenCV级联分类器XML文件github下载地址
4、检测人脸代码:
import cv2
img = cv2.imread("images\\xyj.png") # 读取人脸照片
# 加载识别人脸的级联分类器(haarcascade_frontalface_default.xml)
faceCascade = cv2.CascadeClassifier("cascades\\haarcascade_frontalface_default.xml")
## image:待分析图像;
# scaleFactor:可选参数,扫描图像时的缩放比例;
# minNeighbors:可选参数,临近的检测次数。该值越大,分析误差越小(模糊图片除外)
# flags:默认;minSize、maxSize:最小最大目标尺寸(尺度变换,就是向上或者向下每次是原来的多少倍)
#faces = faceCascade.detectMultiScale(image=, scaleFactor=, minNeighbors=, flags=, minSize=, maxSize=,)
faces = faceCascade.detectMultiScale(img, 1.15, 15) # 检查出所有人脸
for (x, y, w, h) in faces: # 遍历所有人脸的区域
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 5) # 在图像中人脸的位置绘制方框
cv2.imshow("img", img)
cv2.waitKey()
cv2.destroyAllWindows()
运行结果:
5、根据脸部和眼睛的位置特征,对检测到的眼睛加上眼镜,代码:
import cv2
# 覆盖图像
def overlay_img(img, img_over, img_over_x, img_over_y):
img_h, img_w, img_p = img.shape # 背景图像的高、宽、通道数
img_over_h, img_over_w, img_over_c = img_over.shape # 覆盖图像高、宽、通道数
if img_over_c == 3: # 通道数小于等于3
# 转换成4通道图像(四通道就是在三通道的基础上加上Alpha通道,Alpha用来衡量一个像素或图像的透明度;0:完全透明;255:完全不透明)
img_over = cv2.cvtColor(img_over, cv2.COLOR_BGR2BGRA)
for w in range(0, img_over_w): # 遍历(覆盖图像)列
for h in range(0, img_over_h): # 遍历(覆盖图像)行
if img_over[h, w, 3] != 0: # 如果通道4不是全透明的像素(因为所加载的眼镜图片的其它位置都是无像素的)
for c in range(0, 3): # 遍历三个通道
x = img_over_x + w # 覆盖像素的横坐标
y = img_over_y + h # 覆盖像素的纵坐标
if x >= img_w or y >= img_h: # 如果坐标超出最大宽高
break # 不做操作
img[y, x, c] = img_over[h, w, c] # 覆盖像素
return img # 完成覆盖的图像
face_img = cv2.imread("images\\xyj.png") # 读取人脸图像
glass_img = cv2.imread("images\\glass.png", cv2.IMREAD_UNCHANGED) # 读取眼睛图片, 保留图像类型
height, width, channel = glass_img.shape # 获取眼镜图像高、宽、通道数
# 加载级联分类器
face_cascade = cv2.CascadeClassifier("cascades\\haarcascade_frontalface_default.xml")
garyframe = cv2.cvtColor(face_img, cv2.COLOR_BGR2GRAY) # 转为黑白图像
faces = face_cascade.detectMultiScale(garyframe, 1.3, 5) # 识别人脸
for (x, y, w, h) in faces: # 遍历所有人脸的区域
gw = w # 眼镜缩放之后的宽度
gh = int(height * w / width) # 眼镜缩放之后的高度
glass_img = cv2.resize(glass_img, (gw, gh)) # 按照人脸大小缩放眼镜
overlay_img(face_img, glass_img, x, y + int(h * 1 / 3)) # 将眼镜绘制到人脸上
cv2.imshow("screen", face_img) # 显示最终处理的效果
cv2.waitKey()
cv2.destroyAllWindows()
结果:
6、检测眼镜代码:
import cv2
# 读取人脸
img = cv2.imread("images\\xyj.png")
# 加载识别眼镜的级联分类器
eyeCascade = cv2.CascadeClassifier("cascades\\haarcascade_eye.xml")
eyes = eyeCascade.detectMultiScale(img, 1.15) # 识别所有眼镜
for (x, y, w, h) in eyes:
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 5) # 在图像中眼睛的位置绘制方框
cv2.imshow("img", img)
cv2.waitKey()
cv2.destroyAllWindows()
结果
7、小猫的猫脸检测代码:
import cv2
img = cv2.imread("images\\cat.jpg")
# 加载识别类猫脸的级联分类器
catFaceCascade = cv2.CascadeClassifier("cascades\\haarcascade_frontalcatface_extended.xml")
catFace = catFaceCascade.detectMultiScale(img, 1.15, 4) # 识别所有人体
for (x, y, w, h) in catFace: # 遍历所有人体区域
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 5) # 在图像中人体的位置绘制方框
cv2.imshow("img", img)
cv2.waitKey()
cv2.destroyAllWindows()
结果:
8、行人检测代码:
import cv2
img = cv2.imread("images\\monitoring.jpg")
# 加载识别类人体的级联分类器
bodyCascade = cv2.CascadeClassifier("cascades\\haarcascade_fullbody.xml")
bodies = bodyCascade.detectMultiScale(img, 1.15, 4) # 识别所有人体
for (x, y, w, h) in bodies: # 遍历所有人体区域
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 5) # 在图像中人体的位置绘制方框
cv2.imshow("img", img)
cv2.waitKey()
cv2.destroyAllWindows()
结果:
9、汽车车牌检测:
import cv2
img = cv2.imread("images\\car.jpg")
# 加载识别类猫脸的级联分类器
plateCascade = cv2.CascadeClassifier("cascades\\haarcascade_russian_plate_number.xml")
plates = plateCascade.detectMultiScale(img, 1.15, 4) # 识别所有人体
for (x, y, w, h) in plates: # 遍历所有人体区域
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 5) # 在图像中人体的位置绘制方框
cv2.imshow("img", img)
cv2.waitKey()
cv2.destroyAllWindows()
结果:
虽然以上程序对可以对给出的那些图像进行检测,效果也不错。但是经过实验,发现对于其它一些照片的检测效果却不太好。具体情况可以实际操作试试。