1.说明

2.效果

3.准备

3.1 程序准备

3.2 样本数据准备

3.3 正样本VEC文件创建

  [-info <collection_file_name>]  # 记录样本数据的文件(就是我们刚才创建的info.data文件)
  [-img <image_file_name>]    
  [-vec <vec_file_name>]   # 输出文件,内含用于训练的正样本。 
  [-bg <background_file_name>]  # 背景图像的描述文件
  [-num <number_of_samples = 1000>]   #样本数量(默认为1000)
  [-bgcolor <background_color = 0>]    #指定背景颜色
  [-w <sample_width = 24>]#输出样本的宽度(以像素为单位)
  [-h <sample_height = 24>]#输出样本的高度(以像素为单位)

参考

  • 在安装包的这个目录下opencv\build\x64\vc15\bin可以找到opencv_createsamples.exe程序,我们生成下vec文件
D:\opencv3.4.12\opencv\build\x64\vc15\bin\opencv_createsamples.exe -info C:\Users\lng\Desktop\image\positive\info.dat -vec C:\Users\lng\Desktop\image\sample.vec -num 58 -bgcolor 0 -bgthresh 0 -w 24 -h 24
  • 在image目录下就生成了vec文件
    在这里插入图片描述

4.样本数据训练

 -data <cascade_dir_name>     #目录名,如不存在训练程序会创建它,用于存放训练好的分类器
 -vec <vec_file_name>              #包含正样本的vec文件名
 -bg <background_file_name>   #背景描述文件
 [-numPos <number_of_positive_samples = 2000>]   #每级分类器训练时所用的正样本数目
 [-numNeg <number_of_negative_samples = 1000>]   #每级分类器训练时所用的负样本数目
 [-numStages <number_of_stages = 20>]   #训练的分类器的级数
--cascadeParams--
 [-featureType <{HAAR(default), LBP, HOG}>]  # 特征的类型: HAAR - 类Haar特征; LBP - 局部纹理模式特征
 [-w <sampleWidth = 24>] #训练样本的尺寸(单位为像素)
 [-h <sampleHeight = 24>] #训练样本的尺寸(单位为像素)
--boostParams--
 [-minHitRate <min_hit_rate> = 0.995>] #分类器的每一级希望得到的最小检测率
 [-maxFalseAlarmRate <max_false_alarm_rate = 0.5>] #分类器的每一级希望得到的最大误检率

参考

  • 在安装包的这个目录下opencv\build\x64\vc15\bin可以找到opencv_traincascade.exe程序,开始训练样本
  • 这里注意下
    • 指定-bg参数时,文件名前不能加路径,所以需要把刚才在image\negitive下创建的bg.txt文件拷贝到opencv_traincascade.exe程序所在目录下,所以要在bg.txt写负样本图片的绝对路径。
    • 指定numPos参数时,因为每个阶段训练时有些正样本可能会被识别为负样本,故每个训练阶段后都会消耗一定的正样本。因此,此处使用的正样本数量绝对不能等于或超过positive文件夹下的正样本个数,一般留有一定的余量
    • 指定-numNeg参数时,可以多于negitive目录下的负样本数量
D:\opencv3.4.12\opencv\build\x64\vc15\bin\opencv_traincascade.exe -data C:\Users\lng\Desktop\image -vec C:\Users\lng\Desktop\image\sample.vec -bg bg.txt -numPos 50 -numNeg 500 -numStages 12 -feattureType HAAR -w 24 -h 24 -minHitRate 0.995 -maxFalseAlarmRate 0.5
  • 执行结果
PARAMETERS:
cascadeDirName: C:\Users\lng\Desktop\image
vecFileName: C:\Users\lng\Desktop\image\sample.vec
bgFileName: bg.txt
numPos: 50
numNeg: 500
numStages: 12
precalcValBufSize[Mb] : 1024
precalcIdxBufSize[Mb] : 1024
acceptanceRatioBreakValue : -1
stageType: BOOST
featureType: HAAR
sampleWidth: 24
sampleHeight: 24
boostType: GAB
minHitRate: 0.995
maxFalseAlarmRate: 0.5
weightTrimRate: 0.95
maxDepth: 1
maxWeakCount: 100
mode: BASIC
Number of unique features given windowSize [24,24] : 162336
===== TRAINING 0-stage =====
<BEGIN
POS count : consumed   50 : 50
NEG count : acceptanceRatio    500 : 1
Precalculation time: 0.581
+----+---------+---------+
|  N |    HR   |    FA   |
+----+---------+---------+
|   1|        1|        1|
+----+---------+---------+
|   2|        1|     0.05|
+----+---------+---------+
Training until now has taken 0 days 0 hours 0 minutes 1 seconds.
===== TRAINING 1-stage =====
<BEGIN
POS count : consumed   50 : 50
NEG count : acceptanceRatio    500 : 0.084832
Precalculation time: 0.576
+----+---------+---------+
|  N |    HR   |    FA   |
+----+---------+---------+
|   1|        1|        1|
+----+---------+---------+
|   2|        1|    0.146|
+----+---------+---------+
Training until now has taken 0 days 0 hours 0 minutes 3 seconds.
===== TRAINING 2-stage =====
<BEGIN
POS count : consumed   50 : 50
NEG count : acceptanceRatio    500 : 0.0149993
Precalculation time: 0.592
+----+---------+---------+
|  N |    HR   |    FA   |
+----+---------+---------+
|   1|        1|        1|
+----+---------+---------+
|   2|        1|    0.186|
+----+---------+---------+
Training until now has taken 0 days 0 hours 0 minutes 5 seconds.
===== TRAINING 3-stage =====
<BEGIN
POS count : consumed   50 : 50
NEG count : acceptanceRatio    500 : 0.00288033
Precalculation time: 0.652
+----+---------+---------+
|  N |    HR   |    FA   |
+----+---------+---------+
|   1|        1|        1|
+----+---------+---------+
|   2|        1|    0.298|
+----+---------+---------+
Training until now has taken 0 days 0 hours 0 minutes 7 seconds.
===== TRAINING 4-stage =====
<BEGIN
POS count : consumed   50 : 50
NEG count : acceptanceRatio    500 : 0.000768845
Precalculation time: 0.615
+----+---------+---------+
|  N |    HR   |    FA   |
+----+---------+---------+
|   1|        1|        1|
+----+---------+---------+
|   2|        1|        1|
+----+---------+---------+
|   3|        1|    0.366|
+----+---------+---------+
Training until now has taken 0 days 0 hours 0 minutes 11 seconds.
===== TRAINING 5-stage =====
<BEGIN
POS count : consumed   50 : 50
NEG count : acceptanceRatio    500 : 0.000375057
Precalculation time: 0.61
+----+---------+---------+
|  N |    HR   |    FA   |
+----+---------+---------+
|   1|        1|        1|
+----+---------+---------+
|   2|        1|        1|
+----+---------+---------+
|   3|        1|    0.366|
+----+---------+---------+
Training until now has taken 0 days 0 hours 0 minutes 15 seconds.
===== TRAINING 6-stage =====
<BEGIN
POS count : consumed   50 : 50
NEG count : acceptanceRatio    2 : 0.00016276
Required leaf false alarm rate achieved. Branch training t
  • 训练完成后,在img目录下就会生成以下文件。
    在这里插入图片描述
  • cascade.xml就是我们需要的分类器文件,其他都是过程文件。

5.测试代码

#include <iostream>
#include <opencv2/opencv.hpp>
char* face_cascade_name = "C:\\Users\\lng\\Desktop\\image\\cascade.xml";
void faceRecongize(cv::CascadeClassifier faceCascade, cv::Mat frame);
int main(){
    cv::VideoCapture *videoCap = new cv::VideoCapture;
	cv::CascadeClassifier faceCascade;
    // 加载苹果分类器文件
	if (!faceCascade.load(face_cascade_name)) {
		std::cout << "load face_cascade_name failed. " << std::endl;
		return -1;
    // 打开摄像机
	videoCap->open(0);
	if (!videoCap->isOpened()) {
		videoCap->release();
		std::cout << "open camera failed"<< std::endl;
        return -1;
	std::cout << "open camera success"<< std::endl;
    while(1){
		cv::Mat frame;
		//读取视频帧
		videoCap->read(frame);
		if (frame.empty()) {
			videoCap->release();
			return -1;
        //进行苹果识别
		faceRecongize(faceCascade, frame);
        //窗口进行展示
        imshow("face", frame);
        //等待回车键按下退出程序
		if (cv::waitKey(30) == 13) {
			cv::destroyAllWindows();
			return 0;
    system("pause");
    return 0;
void faceRecongize(cv::CascadeClassifier faceCascade, cv::CascadeClassifier eyesCascade, cv::CascadeClassifier mouthCascade, cv::Mat frame) {
	std::vector<cv::Rect> faces;
    // 检测苹果
	faceCascade.detectMultiScale(frame, faces, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, cv::Size(30, 30));
	for (int i = 0; i < faces.size(); i++) {
        // 用椭圆画出苹果部分
        cv::Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);
		ellipse(frame, center, cv::Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, cv::Scalar(255, 0, 255), 4, 8, 0);
		cv::Mat faceROI = frame(faces[i]);
		std::vector<cv::Rect> eyes;
        // 苹果上方区域写字进行标识
		cv::Point centerText(faces[i].x + faces[i].width / 2 - 40, faces[i].y - 20);
		cv::putText(frame, "apple", centerText, cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 0, 255), 2);
cmake_minimum_required (VERSION 3.5)
project (faceRecongize2015)
MESSAGE(STATUS "PROJECT_SOURCE_DIR " ${PROJECT_SOURCE_DIR})
SET(SRC_LISTS ${PROJECT_SOURCE_DIR}/src/main.cpp)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
#set(CMAKE_AUTOMOC ON)
#set(CMAKE_AUTOUIC ON)
#set(CMAKE_AUTORCC ON)
# 配置头文件目录
include_directories(${PROJECT_SOURCE_DIR}/src)
include_directories("D:\\opencv3.4.12\\opencv\\build\\include")
include_directories("D:\\opencv3.4.12\\opencv\\build\\include\\opencv2")
# 设置不显示命令框
if(MSVC)
	#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
endif()
# 添加库文件
set(PRO_OPENCV_LIB "D:\\opencv3.4.12\\opencv\\build\\x64\\vc15\\lib\\opencv_world3412.lib" "D:\\opencv3.4.12\\opencv\\build\\x64\\vc15\\lib\\opencv_world3412d.lib")
IF(WIN32)
    # 生成可执行程序
	ADD_EXECUTABLE(faceRecongize2015 ${SRC_LISTS})
	# 链接库文件
    TARGET_LINK_LIBRARIES(faceRecongize2015 ${PRO_OPENCV_LIB})
ENDIF()

6.编译说明

- src
  - mian.cpp
- build_x64
- CMakeLists
cmake -G "Visual Studio 14 2015 Win64" ..
cmake --build ./ --config Release

备注

ICLR2022/扩散模型/语义分割:基于扩散模型的标签高效语义分割Label-efficient semantic segmentation with diffusion models 2023年2月25日 二次规划问题(qp)和序列二次规划问题(sqp)的简单理解 2023年6月17日 Python — Pandas 模块及常用函数 2022年5月16日 【AIGC】9、BLIP-2 | 使用 Q-Former 连接冻结的图像和语言模型 实现高效图文预训练 2023年5月23日 “讯飞星火”大模型计划10月底赶超ChatGPT 2023年5月30日 综合评价方法 2023年6月10日 隐马尔可夫模型基础介绍 2022年3月14日