opencv 做人脸识别 opencv 人脸匹配分析
发布时间:2023-07-09 06:34:44
机器学习
机器学习的目的是把数据转换成信息。
机器学习通过从数据里提取规则或模式来把数据转成信息。
人脸识别
人脸识别通过级联分类器对特征的分级筛选来确定是否是人脸。
每个节点的正确识别率很高,但正确拒绝率很低。
任一节点判断没有人脸特征则结束运算,宣布不是人脸。
全部节点通过,则宣布是人脸。
工业上,常用人脸识别技术来识别物体。
对图片进行识别
#include "opencv2/core/core.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
string face_cascade_name = "haarcascade_frontalface_alt.xml";
CascadeClassifier face_cascade;
string window_name = "人脸识别";
void detectAndDisplay( Mat frame );
int main( int argc, char** argv ){
Mat image;
image = imread( argv[1]);
if( argc != 2 || !image.data ){
printf("[error] 没有图片\n");
return -1;
}
if( !face_cascade.load( face_cascade_name ) ){
printf("[error] 无法加载级联分类器文件!\n");
return -1;
}
detectAndDisplay(image);
waitKey(0);
}
void detectAndDisplay( Mat frame ){
std::vector<Rect> faces;
Mat frame_gray;
cvtColor( frame, frame_gray, CV_BGR2GRAY );
equalizeHist( frame_gray, frame_gray );
face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
for( int i = 0; i < faces.size(); i++ ){
Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 );
ellipse( frame, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
}
imshow( window_name, frame );
}
CascadeClassifier类
class CascadeClassifier
用于检测物体的级联分类器类。
CascadeClassifier::CascadeClassifier
从一个文件读取分类器。
C++: CascadeClassifier::CascadeClassifier(const string& filename)
参数 filename – 所要读取分类器文件的文件名
参数 | filename – 所要读取分类器文件的文件名 |
---|
CascadeClassifier::empty
检查分类器是否已经载入。
C++: bool CascadeClassifier::empty() const
CascadeClassifier::load
从一个文件读取分类器。
C++: bool CascadeClassifier::load(const string& filename)
参数 filename – 所要读取分类器文件的文件名。文件可以是旧版的HAAR分类器模型也可以是新版的分类器模型。
参数 | filename – 所要读取分类器文件的文件名。文件可以是旧版的HAAR分类器模型也可以是新版的分类器模型。 |
---|
CascadeClassifier::read
读取一个文件存储节点的分类器。
C++: bool CascadeClassifier::read(const FileNode& node)
CascadeClassifier::detectMultiScale
对不同大小的输入图像进行物体识别,并返回一个识别到的物体的矩阵列表。
C++: void CascadeClassifier::detectMultiScale(const Mat& image, vector<Rect>& objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size())
参数 |
|
---|
CascadeClassifier::setImage
设置被用于检测的图像。
C++: bool CascadeClassifier::setImage(Ptr<FeatureEvaluator>& feval, const Mat& image)
参数 |
|
---|
这个函数将在每张图片中被 CascadeClassifier::detectMultiScale() 自动调用。 但如果你想在不同位置手动使用 CascadeClassifier::runAt(),你需要先调用该函数,使得图像被积分计算。
CascadeClassifier::runAt
在指定点运行检测。
C++: int CascadeClassifier::runAt(Ptr<FeatureEvaluator>& feval, Point pt, double& weight)
参数 | feval – 用于特征计算的特征求值程序。 pt – 指定检测窗口左上角的点。窗口的大小和检测的图片大小一致。 |
---|
如果级联分类器检测到给定的位置中的一个对象,该函数返回1。否则,它会返回已被否决的候选区域在哪个阶段的否定的指数。
使用CascadeClassifier::setImage() 设置图像的检测工作。
代码注释:
//需要载入的级联分类器文件
string face_cascade_name = "haarcascade_frontalface_alt.xml";
//级联分类器类
CascadeClassifier face_cascade;
//……
//载入级联分类器,并判断是否载入成功,如果不成功则打印提示
if( !face_cascade.load( face_cascade_name ) ){
printf("[error] 无法加载级联分类器文件!\n");
return -1;
}
//……
//对图片frame进行识别检测
face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
转换成灰度图
由于CascadeClassifier类只支持CV_8U矩阵数据,所以我们需要将图片变成灰度图。
cvtColor API:
将图片从一个色彩空间转到另一个色彩空间。
C++: void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 )
参数 |
|
---|
该函数将输入图片从一个色彩空间转到另一个色彩空间。当从RGB颜色空间进行变换时,应明确指定的信道的顺序(RGB或BGR)。值得注意,在OpenCV的默认颜色格式中,通常被称为作为RGB,但实际上是BGR(字节是相反的)。因此,在一个标准的(24位)的彩 * 像的第一个字节是一个8位的蓝色分量,第二个字节将是绿色的,第三个字节将是红色的。而第四,第五,和第六字节,则是第二像素(蓝,然后绿色,然后红色),依此类推。
R、G和B 通道通常信道值范围:
CV_8U:0 — 255
CV_16U:0 — 65535
CV_32F:0 — 1
线性变换的情况下,有没有范围是无所谓的。但是,在一个非线性变换的情况下,输入的RGB图像应被归为适当的值范围内,以得到正确的结果。例如,如果你有一个32位浮点图像直接转换成一个8位的图像而没有任何缩放,那么它将有0到255的数值范围,而这并不能准确0..1所有浮点数的值。所以,你需要之前调用cvtColor,进行图像缩放。
代码注释:
//将frame转换成灰度图,输出到frame_gray
cvtColor( frame, frame_gray, CV_BGR2GRAY );
直方图均衡化
直方图是图像中像素强度分布的图形表达方式。
它统计了每一个强度值所具有的像素个数。
直方图均衡化是通过拉伸像素强度分布范围来增强图像对比度的一种方法。
说得更清楚一些, 以上面的直方图为例, 你可以看到像素主要集中在中间的一些强度值上. 直方图均衡化要做的就是 拉伸 这个范围. 见下面左图: 绿圈圈出了 少有像素分布其上的 强度值. 对其应用均衡化后, 得到了中间图所示的直方图. 均衡化的图像见下面右图.
我们利用直方图均衡化对图片增强对比度,方便级联分类器分析。
equalizeHist API:
对灰度图像进行直方图均衡。
C++: void equalizeHist(InputArray src, OutputArray dst)
table4
直方图均衡函数使用了下列的算发:
计算源文件的直方图 。
调整直方图,使得其方格总个数为255。
对直方图进行积分:
使用变换图片,其映射函数为:。
该算法归一化亮度并增加了图像的对比度。
猜你喜欢
- 最近“全网域(Web Scale)”一词被炒得火热,人们也正在通过扩展他们的应用程序架构来使他们的系统变得更加“全网域”。但是究竟什么是全网
- 本Demo为练手小项目,主要是熟悉目前主流APP的架构模式.此项目中采用MVC设计模式,纯代码和少许XIB方式实现.主要实现了朋友圈功能和摇
- 一、Flutter代码的启动起点我们在多数的业务场景下,使用的都是FlutterActivity、FlutterFragment。在在背后,
- 最近正式入坑Flutter,首先从环境搭建开始,看了网上好多关于Windows环境搭建的资料,基本都是按官方文档写的,看完的感受是,还不如直
- [LeetCode] 2. Add Two Numbers 两个数字相加You are given two non-empty&n
- JSON.toJSONString()空字段不忽略修改使用JSON.toJSONString(object)方法,返回的json中,默认会将
- 前言上一篇我们认识了Kotlin编程语言,也搭建好开发环境。本篇就进入Kotlin的基础语法介绍,与其他编程语言一样,Kotlin也有自己的
- 这篇文章主要介绍了Java如何实现自定义异常类,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参
- 一、写在前面数据结构中的队列应该是比较熟悉的了,就是先进先出,因为有序故得名队列,就如同排队嘛,在对尾插入新的节点,在对首删除节点.jdk集
- 您已经看到很多包含视频内容的应用程序,比如带有视频教程的食谱应用程序、电影应用程序和体育相关的应用程序。您是否想知道如何将视频内容添加到您的
- 简介对于一个APP来说,肯定会有一个AppBar,这个AppBar一般包含了APP的导航信息等。虽然我们可以用一个固定的组件来做为AppBa
- 一直使用Eclipse环境开发Android,也尝鲜使用过Android Studio去开发,各种IDE配合Android SDK及SDK原
- mport java.text.DecimalFormat; DecimalFormat &nb
- 本文实例为大家分享了Unity实现场景漫游相机的具体代码,供大家参考,具体内容如下前言拿到场景后总喜欢在场景里面玩一段时间,那这个脚本就是你
- SharedPreferences是Android中最容易理解的数据存储技术,实际上SharedPreferences处理的就是一个key-
- 效果展示在实际项目当中我们经常看到如下各种剪裁形状的效果,Flutter 为我们提供了非常方便的 Widget 很轻松就可以实现,下面我们来
- 1.map遍历快速实现边距,文字自适应改变大小Container( // padding: EdgeI
- 接触过Android开发的同学们都知道在Android中访问程序资源基本都是通过资源ID来访问。这样开发起来很简单,并且可以不去考虑各种分辨
- 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。库分静态库和动态库两种。 一、静态库和动态库的区别1. 静态函数库这类库的
- 报错翻译: compileSdkVersion android-24”需要JDK 1.8或更高版本编译。报错现象如下图:原因:st