最近项目上需要用Java做人脸识别,上手了两个星期的Opencv对于人脸识别也有了一定的认识.
首先,我们需要下载Opencv
官网:opencv.org
我用的是4.10版本
点击Release进行下载Opencv
下载好后 在Eclipse中配置Opencv
Window-Perference-Java-Build Path-User Libraries->New
添加一个新的用户库
然后将Opencv目录下Build-Java中的jar包添加进库
然后设置jar包中的Native library location为对应的C++生成的dll文件 一般在OpenCV的jar中的 X64文件夹或者X86
配置好后就可以进行编写代码了
下面是我用到的API 自己通过理解进行翻译的
-------------------------
API
org.opencv.core包
Core类
NATIVE_LIBRARY_NAME 返回一个字符串,内容为库的名称
Mat类(图片类)
Mat(Mat,Rect); 获取一个图片,为分割后的mat
size(); 返回一个Size,行数列数
depth(); 返回一个int,像素深度
channels(); 返回一个int,通道数
rows(); 返回一个int,行数
cols(); 返回一个int,列数
type(); 返回一个int,创建的矩阵的类型
release(); 释放资源-会自动调用,所以一般不需要
clone(); 复制Mat
eye(int rows,int cols,int type);代表一个单位矩阵
dump();
MatOfRect类(图片范围类)
size(); 返回一个Size 输出为到检测的人脸
size(int); 返回一个int 如果int为0 则返回检测到的人脸数量
toArray(); 返回一个Rect数组
CvType类
Scalar类(颜色)
org.opencv.objdetect包
CascadeClassifier类(级联分类器)
load(String fileName); 返回一个boolean 加载OpenCv中的xml文件,加载成功返回true否则返回false
detectMultiScale(Mat,MatOfRect,double,int,int,Size); 通过指定的xml文件检测人脸,将值保存在MatofRect中
mat为输入的灰度图像
MatOfRect为得到被检测物体的矩形框向量组
double为每一个图像尺度中的尺度参数,默认值为1.1,可以决定两个不同大小的窗口扫描之间有多大的跳跃
这个参数设置的大,则意味着计算会变快,但如果窗口错过了某个大小的人脸,则可能丢失物体
int为每一个级联矩形应该保留的临近个数,默认为3,控制着误检测,
默认值为3表明至少有3次重叠检测,我们才认为人脸实存
int对于新的分类器没有用,为0就行
Size指示寻找人脸的最小区域,设置这个参数过大,会以丢失小物体为代价减少计算量
org.opencv.videoio包
VideoCapture类(视频捕捉)
VideoCapture(int index); 如果为0则打开本地摄像头
VideoCapture(String fileName); 读取视频
isOpened(); 返回boolean,视频不能打开返回false
open(String fileName); 读取视频
read(Mat image); 获取,解码并返回下一个视频帧,保存在image内
release(); 关闭
org.opencv.imgproc包
Imgproc类
COLOR_BGR2GRAY; 灰色
cvtColor(Mat,Mat,int,int); 灰度格式
第一个参数是原图像,第二个参数是转换后的图像保存的变量
rectangle(Mat,Rect,Scalar); 画矩形
calcHist
org.opencv.imgcodecs包
Imgcodecs类
imread(String fileName); 返回一个Mat,读取图片
imwrite(String fileName,Mat img); 保存mat为图片,fileName为保存的路径
--------------------------
将库在项目中引用
要想用Opencv首先得加载库
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
做人脸检测很简单
只需要用CascadeClassifier类就行了
加载opencv给我们提供的训练好的xml文件--在Opencv-source-data目录下 我这里用的haarcascades这个目录里的
private CascadeClassifier faceCascade;//人脸检测器static {//加载库System.loadLibrary(Core.NATIVE_LIBRARY_NAME);//获取人脸检测器faceCascade = new CascadeClassifier(人脸的xml文件-haarcascade_frontalface_alt.xml);
}
/*** -检测人脸 根据一张mat*/
public static Mat detectFace(Mat mat) {//检测到的人脸的位置-矩形集MatOfRect rect = new MatOfRect();//进行检测 根据一个Mat,将结果返回到MatOfRect中faceCascade.detectMultiScale(mat,rect);//遍历rect 给每个人脸画个框Rect[] re = rect.toArray();for (Rect r : re) {//给图片上画框框 参数1是图片 参数2是矩形 参数3是颜色 参数四是画出来的线条大小Imgproc.rectangle(mat,r,new Scalar(0,0,255),2);}//输出图片Imgcodecs.imwrite(路径+1.jpg,mat);
}
不同的分类器检测出来的效果也会不同
并且detectMultiScale方法里有很多参数可以设置,更改有不同效果
人脸识别的话首先需要一个人脸库
--这里建议用Javacv 因为要做人脸识别需要contrib模块
JavaCv已经整合好了
目前我的解决方法是用百度AI上进行人脸识别
--------待学习
如果各位有会的话请在下方评论