Opencv_creaatesamples.exe是用来创建样本描述的,创建生成的文件后缀名为.vec,专门为opencv训练准备,只需要对正样本进行创建
Open_haartraining.exe里面封装了haar特征的提取(小波提取,特征黑白提取公式,具体不再这里累述,适用于所有训练的特征,人脸,人眼,人耳等),以及adaboos算法的训练过程。
在进行多次小批量的训练测试后,发现正负样本比例为1:2.67左右的训练结果较好,在这里采取1:3的比例。这个比例不是绝对的,但理论上说,负样本的多样性越大越好,这样的话我们可以有效的降低误检率,而不仅仅是通过正样本的训练让其能够识别物体,在最后训练的时候,我选取了2700个正样本和9000个负样本,且均已转换成灰度图像
在样本准备好之后,打开windows下的cmd窗口,cd到指定目录下,生成所需要的txt
图像目录文件,代码如下(neg_img和pos_img的操作一致):
C:\Users\wz>cd Desktop
C:\Users\wz\Desktop>cd pos_img
C:\Users\wz\Desktop\pos_img>dir /b >pos.txt
[-info <collection_file_name>] //目标图片描述文件,下属命令中为pos.txt
[-img <image_file_name>]
[-vec <vec_file_name>] //指令生成的文件,在下述命令中生成的为pos.vec
[-bg <background_file_name>] //背景图片描述文件,为neg.txt
[-num <number_of_samples = 1000>] //产生的正样本数量
[-bgcolor <background_color = 0>]
[-inv] [-randinv] [-bgthresh <background_color_threshold = 80>]
[-maxidev <max_intensity_deviation = 40>]
[-maxxangle <max_x_rotation_angle = 1.100000>]
[-maxyangle <max_y_rotation_angle = 1.100000>]
[-maxzangle <max_z_rotation_angle = 0.500000>]
[-show [<scale = 4.000000>]]
[-w <sample_width = 24>] //输出的样本宽度20
[-h <sample_height = 24>] //输出的样本高度20
[-pngoutput]
opencv_createsamples.exe -vec pos.vec -info pos_img\pos.txt -bg neg_img\neg.txt -w 20 -h 20 -num 2700
-data <dir_name> //指定存放训练好的分类器的路径名字,在这里为之前在当前目录下建立的xml文件
-vec <vec_file_name> //正样本的文件名(pos.vec)
-bg <background_file_name> //背景描述文件
[-bg-vecfile]
[-npos <number_of_positive_samples = 2000>] //正样本数目2700个
[-nneg <number_of_negative_samples = 2000>] //负样本数目9000个
[-nstages <number_of_stages = 14>] //训练层数
[-nsplits <number_of_splits = 1>] //分裂节点数目为2
[-mem <memory_in_MB = 200>]
[-sym (default)] [-nonsym]
[-minhitrate <min_hit_rate = 0.995000>]
[-maxfalsealarm <max_false_alarm_rate = 0.500000>]
[-weighttrimming <weight_trimming = 0.950000>]
[-eqw]
[-mode <BASIC (default) | CORE | ALL>] //级联器的类型,all表示所有类型
[-w <sample_width = 24>] //样本宽度
[-h <sample_height = 24>] //样本高度
[-bt <DAB | RAB | LB | GAB (default)>]
[-err <misclass (default) | gini | entropy>]
[-maxtreesplits <max_number_of_splits_in_tree_cascade = 0>]
[-minpos <min_number_of_positive_samples_per_cluster = 500>]
opencv_haartraining.exe -vec pos.vec -bg neg_img\neg.txt -data xml -w 20 -h 20 -men 2048 -npos 2700 -nneg 9800 -nstages 9 -mode all
参数意思分别为:
N 对应训练的层数
%SMP 提供样本的使用率
ST.THR 分类器的阈值(这里是极大值)
HR 当前分类器对正样本识别正确的概率
FA 当前分类器对负样本识别错误的概率
EXP.ERR 分类器的期望错误率(基于所提供的样本)
这方面其实有很多,第一就是原先想要加入的方向键控制,在cocos2d里面可能因为疏漏只找到了任意键盘响应,更多的实现实在cocos3d-x中,这一方面是需要后续改进的
还有的方面,比如在识别训练上,haar+adaboost的分类训练虽然是很经典,不过其也有很多缺憾,不够灵活,不过从一个方面看稳定也是他的优点
至于后续,还想研究的就是真正的换脸技术了,dlib的后续模型训练,下一步我想要进行的是将角色的头像进行完美拼接,像下面这样:
------------------------------------------------ 合成------------------------------------------------------
实现最简单的当然是调用shape_68特征点进行替换,并且通过转换进行脸模覆盖
所以下一步,比较想要研究的就是进行完美替换人脸了。
# -*- coding: utf-8 -*-
# import 进openCV的库
import cv2
import sys
import dlib
import cv2
import os
import glob
import numpy as np
import os.path
from PIL import Image
# img_file:图片的路径
# path_save:保存路径
# width:宽度
# height:长度
def img_resize(img_file, path_save, width=16,height=16):
img = Image.open(img_file)
new_image = img.resize((width,height),Image.BILINEAR)
new_image.save(os.path.join(path_save,os.path.basename(img_file)))
#调用电脑摄像头检测人脸并截图
def CatchPICFromVideo(window_name, camera_idx, catch_pic_num, path_name):
cv2.namedWindow(window_name)
#视频来源,可以来自一段已存好的视频,也可以直接来自USB摄像头
cap = cv2.VideoCapture(camera_idx)
#告诉OpenCV使用人脸识别分类器
classfier = cv2.CascadeClassifier('xml.xml')
#识别出人脸后要画的边框的颜色,RGB格式, color是一个不可增删的数组
color = (0, 255, 0)
num = 0
while cap.isOpened():
ok, frame = cap.read() #读取一帧数据
if not ok:
break
grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #将当前桢图像转换成灰度图像
#人脸检测,1.2和2分别为图片缩放比例和需要检测的有效点数
faceRects = classfier.detectMultiScale(grey, scaleFactor = 1.01, minNeighbors = 3, minSize = (212, 212))
if len(faceRects) > 0: #大于0则检测到人脸
for faceRect in faceRects: #单独框出每一张人脸
x, y, w, h = faceRect
#画出矩形框
cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, 2)
#显示当前捕捉到了多少人脸图片了,这样站在那里被拍摄时心里有个数,不用两眼一抹黑傻等着
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(frame,'num:%d/1 %d' % (num,len(faceRects)),(x + 30, y + 30), font, 1, (255,0,255),4)
#超过指定最大保存数量结束程序
# if num > (catch_pic_num): break
#显示图像
cv2.imshow(window_name, frame)
c = cv2.waitKey(10)
if c & 0xFF == ord('q'):
break
#释放摄像头并销毁所有窗口
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
# 连续截100张图像,存进image文件夹中
# CatchPICFromVideo("get face", 0, 2, "C:\\Users\\Administrator\\Desktop\\face_recognition\\faces")
CatchPICFromVideo("get_face", 0, 100, "/home/wz/Desktop/chuangke/simple/")
for jpgfile in glob.glob("/home/wz/Desktop/chuangke/simple/*.jpg"):
img_resize(jpgfile,"/home/wz/Desktop/chuangke/simple/",96,96)
链接: https://pan.baidu.com/s/1ZsBxTdfka0YH2X-gBZSUfA 提取码: 4dx2 //opencv2-4-11版本的exe安装包
链接: https://pan.baidu.com/s/1qP9zR6AUw4xohYriDsvVNw 提取码: inxt //训练所用到的数据data和文件都分享在这里了
若有问题,请评论在博客下方,博主有时间会看的~