mirror of
https://gitee.com/open-visual/face-search.git
synced 2025-07-10 19:37:01 +08:00
update:对InsightScrfd不能正常识别的图像进行补边操作再识别
This commit is contained in:
parent
44d07346c7
commit
667e14cd7e
@ -137,6 +137,18 @@ public class FaceInfo implements Comparable<FaceInfo>, Serializable {
|
||||
public float distance(Point that){
|
||||
return (float) Math.sqrt(Math.pow((this.x-that.x), 2)+Math.pow((this.y-that.y), 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将点进行平移
|
||||
* @param top 向上移动的像素点数
|
||||
* @param bottom 向下移动的像素点数
|
||||
* @param left 向左移动的像素点数
|
||||
* @param right 向右移动的像素点数
|
||||
* @return 平移后的点
|
||||
*/
|
||||
public Point move(int left, int right, int top, int bottom){
|
||||
return new Point(x - left + right, y - top + bottom);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -246,6 +258,22 @@ public class FaceInfo implements Comparable<FaceInfo>, Serializable {
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将点进行平移
|
||||
* @param top 向上移动的像素点数
|
||||
* @param bottom 向下移动的像素点数
|
||||
* @param left 向左移动的像素点数
|
||||
* @param right 向右移动的像素点数
|
||||
* @return 平移后的点
|
||||
*/
|
||||
public Points move(int left, int right, int top, int bottom){
|
||||
Points points = build();
|
||||
for(Point item : this){
|
||||
points.add(item.move(left, right, top, bottom));
|
||||
}
|
||||
return points;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -419,6 +447,23 @@ public class FaceInfo implements Comparable<FaceInfo>, Serializable {
|
||||
new Point(leftBottom.x + change_x_p2_p4, leftBottom.y + change_y_p2_p4)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将框进行平移
|
||||
* @param top 向上移动的像素点数
|
||||
* @param bottom 向下移动的像素点数
|
||||
* @param left 向左移动的像素点数
|
||||
* @param right 向右移动的像素点数
|
||||
* @return 平移后的框
|
||||
*/
|
||||
public FaceBox move(int left, int right, int top, int bottom){
|
||||
return new FaceBox(
|
||||
new Point(leftTop.x - left + right, leftTop.y - top + bottom),
|
||||
new Point(rightTop.x - left + right, rightTop.y - top + bottom),
|
||||
new Point(rightBottom.x - left + right, rightBottom.y - top + bottom),
|
||||
new Point(leftBottom.x - left + right, leftBottom.y - top + bottom)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -252,6 +252,55 @@ public class ImageMat implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对图像进行补边操作,不释放原始的图片
|
||||
* @param top 向上扩展的高度
|
||||
* @param bottom 向下扩展的高度
|
||||
* @param left 向左扩展的宽度
|
||||
* @param right 向右扩展的宽度
|
||||
* @param borderType 补边的类型
|
||||
* @return 补边后的图像
|
||||
*/
|
||||
public ImageMat copyMakeBorderAndNotReleaseMat(int top, int bottom, int left, int right, int borderType){
|
||||
return this.copyMakeBorder(top, bottom, left, right, borderType, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对图像进行补边操作,并且释放原始的图片
|
||||
* @param top 向上扩展的高度
|
||||
* @param bottom 向下扩展的高度
|
||||
* @param left 向左扩展的宽度
|
||||
* @param right 向右扩展的宽度
|
||||
* @param borderType 补边的类型
|
||||
* @return 补边后的图像
|
||||
*/
|
||||
public ImageMat copyMakeBorderAndDoReleaseMat(int top, int bottom, int left, int right, int borderType){
|
||||
return this.copyMakeBorder(top, bottom, left, right, borderType, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对图像进行补边操作
|
||||
* @param top 向上扩展的高度
|
||||
* @param bottom 向下扩展的高度
|
||||
* @param left 向左扩展的宽度
|
||||
* @param right 向右扩展的宽度
|
||||
* @param borderType 补边的类型
|
||||
* @param release 是否释放原始的图片
|
||||
* @return 补边后的图像
|
||||
*/
|
||||
private ImageMat copyMakeBorder(int top, int bottom, int left, int right, int borderType, boolean release){
|
||||
try {
|
||||
Mat tempMat = new Mat();
|
||||
Core.copyMakeBorder(mat, tempMat, top, bottom, left, right, borderType);
|
||||
return new ImageMat(tempMat);
|
||||
}finally {
|
||||
if(release){
|
||||
this.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对图像进行预处理,不释放原始图片数据
|
||||
* @param scale 图像各通道数值的缩放比例
|
||||
|
@ -7,6 +7,9 @@ import com.visual.face.search.core.base.BaseOnnxInfer;
|
||||
import com.visual.face.search.core.base.FaceDetection;
|
||||
import com.visual.face.search.core.domain.FaceInfo;
|
||||
import com.visual.face.search.core.domain.ImageMat;
|
||||
import com.visual.face.search.core.utils.ReleaseUtil;
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.Scalar;
|
||||
|
||||
import java.util.*;
|
||||
@ -32,6 +35,10 @@ public class InsightScrfdFaceDetection extends BaseOnnxInfer implements FaceDete
|
||||
public final static boolean defNeedCheckFaceAngle = true;
|
||||
//是否需要进行角度检测的参数KEY
|
||||
public final static String scrfdFaceNeedCheckFaceAngleParamKey = "scrfdFaceNeedCheckFaceAngle";
|
||||
//人脸框默认需要进行角度检测
|
||||
public final static boolean defNoFaceImageNeedMakeBorder = true;
|
||||
//是否需要进行角度检测的参数KEY
|
||||
public final static String scrfdNoFaceImageNeedMakeBorderParamKey = "scrfdNoFaceImageNeedMakeBorder";
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
@ -51,6 +58,40 @@ public class InsightScrfdFaceDetection extends BaseOnnxInfer implements FaceDete
|
||||
*/
|
||||
@Override
|
||||
public List<FaceInfo> inference(ImageMat image, float scoreTh, float iouTh, Map<String, Object> params) {
|
||||
List<FaceInfo> faceInfos = this.modelInference(image, scoreTh,iouTh, params);
|
||||
//对图像进行补边操作,进行二次识别
|
||||
if(this.getNoFaceImageNeedMakeBorder(params) && faceInfos.isEmpty()){
|
||||
//防止由于人脸占用大,导致检测模型识别失败
|
||||
int t = Double.valueOf(image.toCvMat().height() * 0.2).intValue();
|
||||
int b = Double.valueOf(image.toCvMat().height() * 0.2).intValue();
|
||||
int l = Double.valueOf(image.toCvMat().width() * 0.2).intValue();
|
||||
int r = Double.valueOf(image.toCvMat().width() * 0.2).intValue();
|
||||
ImageMat tempMat = null;
|
||||
try {
|
||||
//补边识别
|
||||
tempMat=image.copyMakeBorderAndNotReleaseMat(t, b, l, r, Core.BORDER_CONSTANT);
|
||||
faceInfos = this.modelInference(tempMat, scoreTh,iouTh, params);
|
||||
for(FaceInfo faceInfo : faceInfos){
|
||||
//还原原始的坐标
|
||||
faceInfo.box = faceInfo.box.move(l, 0, t, 0);
|
||||
faceInfo.points = faceInfo.points.move(l, 0, t, 0);
|
||||
}
|
||||
}finally {
|
||||
ReleaseUtil.release(tempMat);
|
||||
}
|
||||
}
|
||||
return faceInfos;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 模型推理,获取人脸信息
|
||||
* @param image 图像信息
|
||||
* @param scoreTh 人脸人数阈值
|
||||
* @param iouTh 人脸iou阈值
|
||||
* @return 人脸模型
|
||||
*/
|
||||
public List<FaceInfo> modelInference(ImageMat image, float scoreTh, float iouTh, Map<String, Object> params) {
|
||||
OnnxTensor tensor = null;
|
||||
OrtSession.Result output = null;
|
||||
ImageMat imageMat = image.clone();
|
||||
@ -252,4 +293,24 @@ public class InsightScrfdFaceDetection extends BaseOnnxInfer implements FaceDete
|
||||
}
|
||||
return needCheckFaceAngle;
|
||||
}
|
||||
|
||||
/**获取是否需要对没有检测到人脸的图像进行补边二次识别**/
|
||||
private boolean getNoFaceImageNeedMakeBorder(Map<String, Object> params){
|
||||
boolean noFaceImageNeedMakeBorder = defNoFaceImageNeedMakeBorder;
|
||||
try {
|
||||
if(null != params && params.containsKey(scrfdNoFaceImageNeedMakeBorderParamKey)){
|
||||
Object value = params.get(scrfdNoFaceImageNeedMakeBorderParamKey);
|
||||
if(null != value){
|
||||
if (value instanceof Boolean){
|
||||
noFaceImageNeedMakeBorder = (boolean) value;
|
||||
}else{
|
||||
noFaceImageNeedMakeBorder = Boolean.parseBoolean(value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return noFaceImageNeedMakeBorder;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user