基于openCV4和MFC的口罩识别系统总结

知识点整理

HSV色彩空间

  • HSV色彩空间:HSV(色相/饱和度/明度)颜色空间是表示类似于RGB颜色模型的颜色空间的模型。饱和度的变化代表颜色成分的多少。明度通道描述颜色的亮度。
  • 色调(hue)表示主色,我们使用的颜色名称(例如绿色、 黄色和红色)就对应了不同的色调值;饱和度(saturation)表示颜色的鲜艳程度,柔和的颜色饱 和度较低,而彩虹的颜色饱和度就很高亮度(brightness)是一个主观的属性,表示某种颜色的光亮程度。
  • 肤色的色调范围有论文数据:H∈[34°,50°]
  • HSV中只有Hue一个通道表示颜色:根据色相通道(Channel)对颜色类型进行建模,因此在需要根据颜色对对象进行分割的图像处理任务中非常有用。
    -RGB颜色空间中的颜色使用三个通道对进行编码,因此基于颜色对图像中的对象进行分割更加困难。
  • 使用OpenCV cv :: inRange函数执行基本阈值操作。基于HSV颜色空间中的像素值范围来检测对象。
// inRange()函数讲解
void inRange(    InputArray src,
                InputArray lowerb,  
                InputArray upperb,   
                OutputArray dst);

第一个参数:输入图像
第二个参数:H、S、V的最小值,示例:Scalar(low_H, low_S, low_V)
第三个参数:H、S、V的最大值,示例:Scalar(low_H, low_S, low_V)
第四个参数:输出图像,要和输入图像有相同的尺寸且为CV_8U类
 // 使用举例
 Mat hsv = image.clone();
 Mat frame_threshold = image.clone();
 cvtColor(image, hsv, COLOR_BGR2HSV);
 double low_H = 35;
 double low_S = 43;
 double low_V = 46;
 double high_H = 77;
 double high_S = 255;
 double high_V = 255;
 inRange(hsv, Scalar(low_H, low_S, low_V), Scalar(high_H, high_S, high_V), frame_threshold);

openCV图像像素操作

  • RGB色彩空间inputmat.at(x, y):三通道分别为BGR,而不是RGB
// 这里inputmat是二值化图像的mat
inputmat.at<Vec3b>(x, y)[0];// 第一个通道,对应于BGR类型的蓝色通道
inputmat.at<Vec3b>(x, y)[1];// 第一个通道,对应于BGR类型的绿色通道
inputmat.at<Vec3b>(x, y)[2];// 第一个通道,对应于BGR类型的红色通道
  • HSV色彩空间inputmat.at(x, y)
// 这里inputmat是二值化图像的mat
inputmat.at<Vec3b>(x, y)[0];// 第一个通道,H:色相
inputmat.at<Vec3b>(x, y)[1];// 第一个通道,S:饱和度
inputmat.at<Vec3b>(x, y)[2];// 第一个通道,V:明度
  • 二值化色彩空间:二值化图像像素不是0(黑色)就是255(白色),数据类型为uchar
// 这里inputmat是二值化图像的mat
inputmat.at<uchar>(x, y);
if (inputmat.at<uchar>(x, y) == 255){
	//白色像素点
}
if (inputmat.at<uchar>(x, y) == 0){
	//黑色像素点
}

人脸检测方法分类

描述一: 常见人脸区域检测技术有基于VJ 算法,DPM 模型, 深度学习框架。

  • VJ算法:VIola-Jones 是传统人脸检测算法。OpenCV 中的人脸检测也是用的这种算法。有三个步骤: Harr-like特征,Adaboost分类和级联分类。以下是算法的关键点:运用Harr-like输入特征: 阈值化矩形图像的和或差; 图像45 度旋转运用了积分图像技术, 加速计算类Harr; 运用Adaboost 创建分类器, 区分人脸与非人脸。筛选式级联分类器节点。第一组性能最优, 第二组次之, 以此类推。但是Harr-like特征只能创建简单的特征, 面对难样本稳定性低; 弱分类器采用的简单决策树,造成过拟合问题。分类器以VJ-cascade 为基础, 在进入下一个步骤前,信息全部被丢弃, 鲁棒性较弱。
  • DMP模型:运用FHOG进行特征选取, 依据PCA的结果选择维特征。基于DMP 的人脸检测方法在随机采集的图片上获得比VJ 算法更好的效果。但是模型太过复杂,不能达到实时性的要求。后续有加入级联分类器, 使用积分图法进行特征计算,但是没有VJ效率高。
  • 深度学习框架:经典人脸检测方法络并不能达到稳定性要求, 容易受到光照, 遮挡, 调度的影响, 在复杂场景下保证人脸检测的识别率就很困难, 因此使用场景受限后续很多的人脸检测方法几乎都是根据深度神经网络进行优化的算法。精度上超越了之前的Adaboost框架。目前, 使用卷积神经网络进行的人脸检测方法能够解决运用滑动选框进行的人脸检测很难达到实时性要求这个问题。

描述二: 人脸检测方法可大致分为基于外部特征、模板匹配和统计型的人脸检测

  • 基于外观不变特征的人脸检测:人脸的一些特征比如几何、肤色等不受姿态表情变化影响,所以可以通过特定的算法提取相应脸部征, 并对这些特征进行建模。
  • 基于模板匹配的人脸检测:将事先准备好的一个人脸模板作为描述子,在视频流或图片输入时从左上方开始逐像素的进行扫描、匹配。
  • 基于统计模型的人脸检测:基于统计模型的人脸检测不需要对图片进行相关的预处理,并且不需要准备人脸模板。此方法是利用某种算法或者多种算法的融合对大量的样本图片(包含人脸和非人脸)进行学习,紧接着训练出一个人脸分类器,利用此分类器可以快速在输入视频的每一帧中检测出人脸并标记。基于统计模型的人脸检测需要在训练阶段采用大量的样本图片对该训练器进行训练,虽然算法过程较复杂,但是其检测效果速度快,检测率高,是目前的人脸检测主流方法。

描述三: 现有的人脸捡测方法大致可分为四种:基于知识的方法、特征不变方法、模板匹配方法、基于外观的方法

  • 基于知识的方法:基于规则的人脸检测方法,如人脸肤色、几何结构、人脸轮廓等特征。
  • 特征不变方法:根据提取到的面部特征,构建统计模型描述特征之间的相互关系并确定存在的人脸。
  • 模板匹配方法:预先存储几种标准的人脸模式描述整个人脸和面特征。计算输入图像和存储模式之间的相互关系, 根据计算得到的相互关系用于人脸检测。
  • 基于外观的方法:利用机器学习和统计分析找到人脸和非人脸的特征。

Opencv 中 CV_8UC1,CV_32FC3等参数的含义

#define CV_8SC1 CV_MAKETYPE(CV_8S,1)
#define CV_8SC2 CV_MAKETYPE(CV_8S,2)
#define CV_8SC3 CV_MAKETYPE(CV_8S,3)
#define CV_8SC4 CV_MAKETYPE(CV_8S,4)
#define CV_8SC(n) CV_MAKETYPE(CV_8S,(n))

#define CV_16UC1 CV_MAKETYPE(CV_16U,1)
#define CV_16UC2 CV_MAKETYPE(CV_16U,2)
#define CV_16UC3 CV_MAKETYPE(CV_16U,3)
#define CV_16UC4 CV_MAKETYPE(CV_16U,4)
#define CV_16UC(n) CV_MAKETYPE(CV_16U,(n))


#define CV_32SC1 CV_MAKETYPE(CV_32S,1)
#define CV_32SC2 CV_MAKETYPE(CV_32S,2)
#define CV_32SC3 CV_MAKETYPE(CV_32S,3)
#define CV_32SC4 CV_MAKETYPE(CV_32S,4)
#define CV_32SC(n) CV_MAKETYPE(CV_32S,(n))

#define CV_64FC1 CV_MAKETYPE(CV_64F,1)
#define CV_64FC2 CV_MAKETYPE(CV_64F,2)
#define CV_64FC3 CV_MAKETYPE(CV_64F,3)
#define CV_64FC4 CV_MAKETYPE(CV_64F,4)
#define CV_64FC(n) CV_MAKETYPE(CV_64F,(n))

  • 预定义类型的结构如下所示:
CV_<bit_depth>(S|U|F)C<number_of_channels>
  • bit_depth—比特数—代表8bite,16bites,32bites,64bites—
    表示每一个像素点在内存空间所占的空间大小
  • S|U|F:代表数据类型
S--代表—signed int—有符号整形,
U–代表–unsigned int–无符号整形,
F–代表–float-------单精度浮点型
  • C代表—一张图片的通道数,比如:
1–灰度图片–grayImg—是–单通道图像
2–RGB彩色图像---------是–3通道图像
3–带Alph通道的RGB图像–是--4通道图像

基于均值感知哈希算法的视觉目标跟踪

  • 一张图片就是一个二维信号,它包含了不同频率的成分。亮度变化小的区域是低频成分,它描述大范围的信息。而亮度变化剧烈的区域(比如物体的边缘)就是高频的成分,它描述具体的细节。或者说高频可以提供图片详细的信息,而低频可以提供一个框架。
  • 原理:对每张图片生成一个“指纹”(fingerprint)字符串,然后比较不同图片的指纹。结果越接近,就说明图片越相似。
  • 感知哈希算法的视觉跟踪:首先我们把要跟踪的目标保存好,计算它的hash码,然后在每一帧来临的时候,扫描整个图像,计算每个扫描窗口的hash码,比较它和目标的hash码的Hamming distance,Hamming distance最小的扫描窗口就是和目标最相似的,也就是该帧的目标所在位置。
  • 均值哈希虽然简单,但受均值的影响非常大。例如对图像进行伽马校正或直方图均衡就会影响均值,从而影响最终的hash值。存在一个更健壮的算法叫pHash。它将均值的方法发挥到极致。使用离散余弦变换(DCT)来获取图片的低频成分。pHash算法参考链接

算法原理

  • 第一步,缩小尺寸。将图片缩小到8x8的尺寸,总共64个像素。这一步的作用是去除图片的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。
  • 第二步,简化色彩。将缩小后的图片,转为64级灰度。也就是说,所有像素点总共只有64种色。
  • 第三步,计算平均值。计算所有64个像素的灰度平均值。
  • 第四步,比较像素的灰度。将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。
  • 第五步,计算哈希值。将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。
  • 第六步,得到指纹以后,就可以对比不同的图片,看看64位中有多少位是不一样的。在理论上,这等同于计算"汉明距离"(Hamming distance)。如果不相同的数据位不超过5,就说明两张图片很相似;如果大于10,就说明这是两张不同的图片。

肤色检测

-方法一: 基于RGB的肤色检测

在均匀光照下应满足以下判别式:

R>95 AND G>40 B>20 AND MAX(R,G,B)-MIN(R,G,B)>15 AND ABS(R-G)>15 AND R>G AND R>B

在侧光拍摄环境下:

R>220 AND G>210 AND B>170 AND ABS(R-G)<=15 AND R>B AND G>B

  • 方法二:基于椭圆皮肤模型的皮肤检测
  • 方法三:YCrCb颜色空间Cr分量+Otsu法阈值分割
该方法的原理:
a.将RGB图像转换到YCrCb颜色空间,提取Cr分量图像
b.对Cr做自二值化阈值分割处理(Otsu法)
  • 方法四:基于YCrCb颜色空间Cr,Cb范围筛选法
  • 方法五:HSV颜色空间H范围筛选法
  • 方法六:基于opencv自带肤色检测类AdaptiveSkinDetector
    参考链接

LBP人脸识别

  • 基本思想:在33的窗口内,以窗口中心像素为阈值,将相邻的8个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为1,否则为0。这样,33邻域内的8个点经过比较可产生8位二进制数,,即得到该窗口中心像素点的LBP值,并用这个值来反映该区域的纹理信息。
  • 通过对全局图像进行LBP特征提取得到LBP图,LBP特征图是不能直接来作人脸识别的,需要对LBP特征图进行分块并计算每个分块的直方图,通过直方图的统计信息进行识别,最后将各块的直方图首尾相连就得到一张图片最终的LBP特征描述向量。计算两张图片的LBP特征向量的相似度即可实现人脸识别。
  • OpenCV中LBPH人脸识别类如下进行创建
Ptr<FaceRecognizer> LBPHRecog = createLBPHFaceRecognizer(1, 8 ,3, 3, 50);         //构造LBPH人脸识别类的对象并初始化

int radius = 1 :中心像素点到周围像素点的距离,相邻像素距离为1,以此类推
int neighbors = 8 :选取的周围像素点的个数
int grid_x= 8 :将一张图片在x方向分成8int grid_y = 8 :将一张图片在y方向分成8double threshold = DBL_MAX  :LBP特征向量相似度的阈值,只有两张图片的相似度小于阈值才可认为识别有效,大于阈值则返回-1
 LBPHRecog->train(trainPic, labels);         //LBP人脸识别训练函数
 
训练函数参数中的trainPic是一个vector,所有需要训练的图片都被包含在内,labels也是vector,存储与trainPic中对应训练图片的名字,这样从trainPic中得到的与识别的图片最相似的图片的名字即可在labels中查找到。
result = LBPHRecog->predict(recogPic);//进行识别,并返回识别结果
  • 参考链接1
  • 参考链接2

openCV轮廓检测

-openCV中通过使用findContours函数,简单几个的步骤就可以检测出物体的轮廓,参考链接

  • 函数原型
findContours( InputOutputArray image, OutputArrayOfArrays contours,
                              OutputArray hierarchy, int mode,
                              int method, Point offset=Point());
  • 第一个参数:image,单通道图像矩阵,可以是灰度图,但更常用的是二值图像,一般是经过Canny、拉普拉斯等边缘检测算子处理过的二值图像
  • 第二个参数:contours,定义为vector> contours,是一个向量,并且是一个双重向量,向量内每个元素保存了一组由连续的Point点构成的点的集合的向量,每一组Point点集就是一个轮廓。 有多少轮廓,向量contours就有多少元素。
  • 第三个参数:hierarchy,定义为vector hierarchy 轮廓特征
  • 第四个参数:int型的mode,定义轮廓的检索模式:
取值一:CV_RETR_EXTERNAL只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略

取值二:CV_RETR_LIST   检测所有的轮廓,包括内围、外围轮廓,但是检测到的轮廓不建立等级关 系,彼此之间独立,没有等级关系,这就意味着这个检索模式下不存在父轮廓或内嵌轮廓, 所以hierarchy向量内所有元素的第3、第4个分量都会被置为-1,具体下文会讲到

取值三:CV_RETR_CCOMP  检测所有的轮廓,但所有轮廓只建立两个等级关系,外围为顶层,若外围 内的内围轮廓还包含了其他的轮廓信息,则内围内的所有轮廓均归属于顶层

取值四:CV_RETR_TREE, 检测所有轮廓,所有轮廓建立一个等级树结构。外层轮廓包含内层轮廓,内层轮廓还可以继续包含内嵌轮廓。
  • 第五个参数:int型的method,定义轮廓的近似方法:
取值一:CV_CHAIN_APPROX_NONE 保存物体边界上所有连续的轮廓点到contours向量内

取值二:CV_CHAIN_APPROX_SIMPLE 仅保存轮廓的拐点信息,把所有轮廓拐点处的点保存入contours向量内,拐点与拐点之间直线段上的信息点不予保留

取值三和四:CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法
  • 第六个参数:Point偏移量,所有的轮廓信息相对于原始图像对应点的偏移量,相当于在每一个检测出的轮廓点上加上该偏移量,并且Point还可以是负值!

你可能感兴趣的:(学习笔记)