最近一直在捣腾openCV,看到美颜相机的眼睛放大觉得很好玩。本篇文章主要讨论:使用openCV做人脸检测、眼睛检测,然后实现人脸和眼睛的局部放大。当然这不仅局限于人脸于眼睛放大,可以做图片的任意区域的局部放大。
1、使用openCV时,先进行初始化:
/**
* 初始化openCV
*/
private void initOpenCV(){
boolean result = OpenCVLoader.initDebug();
if(result){
Log.i(TAG, "initOpenCV success...");
}else {
Log.e(TAG, "initOpenCV fail...");
}
}
2、然后初始化人脸和眼睛检测器:
/**
* 初始化人脸和眼睛检测器
* @param context context
*/
public void initDetector(Context context){
mFaceRect = new MatOfRect();
mFaceDetector = new ObjectDetector(context, R.raw.lbpcascade_frontalface,
2, 0.2F, 0.2F,
new Scalar(0, 0, 255, 0));
mEyeRect = new MatOfRect();
mEyeDetector = new ObjectDetector(context, R.raw.haarcascade_eye,
2, 0.1F, 0.1F,
new Scalar(0, 0, 255, 0));
}
3、使用人脸检测器去检测人脸:
/**
* 检测人脸
*/
private void detectFace(){
Mat mGray = new Mat();
Imgproc.cvtColor(mat, mGray, Imgproc.COLOR_RGBA2GRAY);
Rect[] faceRect = mFaceDetector.detectObject(mGray, mFaceRect);
if(faceRect != null && faceRect.length > 0){
Rect face = faceRect[0];
//矩形标识
Imgproc.rectangle(mat, face.tl(), face.br(),
mFaceDetector.getRectColor(), 3);
//待放大区域
Mat zoomMat = mat.submat((int) face.tl().y, (int) face.br().y, (int) face.tl().x, (int) face.br().x);
zoomOut(mat, zoomMat);
}
mGray.release();
}
局部放大的方法,使用resize方法实现,默认放大倍数为1.5倍:
/**
* 局部放大
* @param srcMat srcMat
* @param zoomMat zoomMat
*/
private void zoomOut(Mat srcMat, Mat zoomMat){
double rowEnd = zoomMat.rows() * 1.5 < srcMat.rows() ? zoomMat.rows() * 1.5 : srcMat.rows();
double colEnd = zoomMat.cols() * 1.5 < srcMat.cols() ? zoomMat.cols() * 1.5 : srcMat.cols();
Mat zoomCorner = srcMat.submat(0, (int)rowEnd, 0, (int)colEnd);
Imgproc.resize(zoomMat, zoomCorner, zoomCorner.size());
zoomCorner.release();
zoomMat.release();
Utils.matToBitmap(srcMat, bitmap);
img_zoom.setImageBitmap(bitmap);
}
让我们看下人脸放大效果:
接下来,使用眼睛检测器去检测眼睛:
/**
* 检测眼睛
*/
private void detectEye(){
Mat mGray = new Mat();
Imgproc.cvtColor(mat, mGray, Imgproc.COLOR_RGBA2GRAY);
Rect[] eyeRect = mEyeDetector.detectObject(mGray, mEyeRect);
if(eyeRect != null && eyeRect.length >= 2){
//矩形标识
Imgproc.rectangle(mat, eyeRect[0].tl(), eyeRect[1].br(),
mFaceDetector.getRectColor(), 3);
//待放大区域
Mat zoomMat = mat.submat((int) eyeRect[0].tl().y, (int) eyeRect[1].br().y,
(int) eyeRect[0].tl().x, (int) eyeRect[1].br().x);
zoomOut(mat, zoomMat);
}
mGray.release();
}
最后看下眼睛放大的效果(注意这里不是原位置放大,如果要做相机美颜效果需要稍作修改):
好了,图片的局部放大分析完毕。各位如果有问题或者建议,欢迎交流。。。