Browse Source

init

master
divenswu 2 years ago
parent
commit
b71ae4dea8
  1. 23
      open-anpr-core/src/main/java/com/visual/open/anpr/core/base/PlateDetection.java
  2. 39
      open-anpr-core/src/main/java/com/visual/open/anpr/core/domain/ImageMat.java
  3. 44
      open-anpr-core/src/main/java/com/visual/open/anpr/core/models/PaddlePlateDetection.java
  4. 24
      open-anpr-core/src/main/java/com/visual/open/anpr/core/utils/CropUtil.java
  5. 111
      open-anpr-core/src/main/java/com/visual/open/anpr/core/utils/MaskUtil.java
  6. 39
      open-anpr-core/src/main/java/com/visual/open/anpr/core/utils/PointUtil.java
  7. 15
      open-anpr-core/src/main/java/com/visual/open/anpr/core/utils/ReleaseUtil.java
  8. 4
      open-anpr-core/src/main/java/com/visual/open/anpr/core/utils/Similarity.java

23
open-anpr-core/src/main/java/com/visual/open/anpr/core/base/PlateDetection.java

@ -0,0 +1,23 @@
package com.visual.open.anpr.core.base;
import com.visual.open.anpr.core.domain.ImageMat;
import com.visual.open.anpr.core.domain.PlateInfo;
import java.util.List;
import java.util.Map;
public interface PlateDetection {
/**
*获取人脸信息
* @param image 图像信息
* @param scoreTh 人脸人数阈值
* @param iouTh 人脸iou阈值
* @param params 参数信息
* @return
*/
List<PlateInfo> inference(ImageMat image, float scoreTh, float iouTh, Map<String, Object> params);
}

39
open-anpr-core/src/main/java/com/visual/open/anpr/core/domain/ImageMat.java

@ -474,10 +474,17 @@ public class ImageMat implements Serializable {
* @return * @return
*/ */
private float[][][][] to4dFloatArray(boolean firstChannel, boolean release){ private float[][][][] to4dFloatArray(boolean firstChannel, boolean release){
try { return to4dFloatArray(firstChannel, new float[]{1, 1, 1}, release);
}
float std[] = {0.229f, 0.224f, 0.225f};
/**
* 转换为单精度形数组
* @param firstChannel
* @param release 是否释放参数mat
* @return
*/
private float[][][][] to4dFloatArray(boolean firstChannel, float[] std, boolean release){
try {
int width = this.mat.cols(); int width = this.mat.cols();
int height = this.mat.rows(); int height = this.mat.rows();
int channel = this.mat.channels(); int channel = this.mat.channels();
@ -637,6 +644,19 @@ public class ImageMat implements Serializable {
} }
} }
/**
* 转换为单精度形OnnxTensor,不释放原始图片数据
* @param firstChannel
* @return
*/
public OnnxTensor to4dFloatOnnxTensorAndNoReleaseMat(float[] std, boolean firstChannel) {
try {
return OnnxTensor.createTensor(env, this.to4dFloatArray(firstChannel, std, false));
}catch (Exception e){
throw new RuntimeException(e);
}
}
/** /**
* 转换为单精度形OnnxTensor,并释放原始图片数据 * 转换为单精度形OnnxTensor,并释放原始图片数据
* @param firstChannel * @param firstChannel
@ -650,6 +670,19 @@ public class ImageMat implements Serializable {
} }
} }
/**
* 转换为单精度形OnnxTensor,并释放原始图片数据
* @param firstChannel
* @return
*/
public OnnxTensor to4dFloatOnnxTensorAndDoReleaseMat(float[] std, boolean firstChannel) {
try {
return OnnxTensor.createTensor(env, this.to4dFloatArray(firstChannel, std, true));
}catch (Exception e){
throw new RuntimeException(e);
}
}
/** /**
* 转换为双精度形OnnxTensor,不释放原始图片数据 * 转换为双精度形OnnxTensor,不释放原始图片数据
* @param firstChannel * @param firstChannel

44
open-anpr-core/src/main/java/com/visual/open/anpr/core/models/PaddlePlateDetection.java

@ -0,0 +1,44 @@
package com.visual.open.anpr.core.models;
import ai.onnxruntime.OnnxTensor;
import com.visual.open.anpr.core.base.BaseOnnxInfer;
import com.visual.open.anpr.core.base.PlateDetection;
import com.visual.open.anpr.core.domain.ImageMat;
import com.visual.open.anpr.core.domain.PlateInfo;
import com.visual.open.anpr.core.utils.ReleaseUtil;
import org.opencv.core.Scalar;
import java.util.List;
import java.util.Map;
public class PaddlePlateDetection extends BaseOnnxInfer implements PlateDetection {
private float std[] = {0.229f, 0.224f, 0.225f};
private Scalar mean = new Scalar(0.485, 0.456, 0.406);
public PaddlePlateDetection(String modelPath, int threads) {
super(modelPath, threads);
}
@Override
public List<PlateInfo> inference(ImageMat image, float scoreTh, float iouTh, Map<String, Object> params) {
ImageMat imageMat = image.clone();
OnnxTensor tensor = null;
try {
tensor = imageMat
.blobFromImageAndDoReleaseMat(1.0/255, mean, true)
.to4dFloatOnnxTensorAndNoReleaseMat(std,true);
}catch (Exception e){
}finally {
ReleaseUtil.release(tensor);
}
return null;
}
}

24
open-anpr-core/src/main/java/com/visual/open/anpr/core/utils/CropUtil.java

@ -1,6 +1,6 @@
package com.visual.open.anpr.core.utils; package com.visual.open.anpr.core.utils;
import com.visual.face.search.core.domain.FaceInfo; import com.visual.open.anpr.core.domain.PlateInfo;
import org.opencv.core.CvType; import org.opencv.core.CvType;
import org.opencv.core.Mat; import org.opencv.core.Mat;
import org.opencv.core.Point; import org.opencv.core.Point;
@ -19,29 +19,29 @@ public class CropUtil {
/** /**
* 根据4个点裁剪图像 * 根据4个点裁剪图像
* @param image * @param image
* @param faceBox * @param plateBox
* @return * @return
*/ */
public static Mat crop(Mat image, FaceInfo.FaceBox faceBox){ public static Mat crop(Mat image, PlateInfo.PlateBox plateBox){
Mat endM = null; Mat endM = null;
Mat startM = null; Mat startM = null;
Mat perspectiveTransform = null; Mat perspectiveTransform = null;
try { try {
List<Point> dest = new ArrayList<>(); List<Point> dest = new ArrayList<>();
dest.add(new Point(faceBox.leftTop.x, faceBox.leftTop.y)); dest.add(new Point(plateBox.leftTop.x, plateBox.leftTop.y));
dest.add(new Point(faceBox.rightTop.x, faceBox.rightTop.y)); dest.add(new Point(plateBox.rightTop.x, plateBox.rightTop.y));
dest.add(new Point(faceBox.rightBottom.x, faceBox.rightBottom.y)); dest.add(new Point(plateBox.rightBottom.x, plateBox.rightBottom.y));
dest.add(new Point(faceBox.leftBottom.x, faceBox.leftBottom.y)); dest.add(new Point(plateBox.leftBottom.x, plateBox.leftBottom.y));
startM = Converters.vector_Point2f_to_Mat(dest); startM = Converters.vector_Point2f_to_Mat(dest);
List<Point> ends = new ArrayList<>(); List<Point> ends = new ArrayList<>();
ends.add(new Point(0, 0)); ends.add(new Point(0, 0));
ends.add(new Point(faceBox.width(), 0)); ends.add(new Point(plateBox.width(), 0));
ends.add(new Point(faceBox.width(), faceBox.height())); ends.add(new Point(plateBox.width(), plateBox.height()));
ends.add(new Point(0, faceBox.height())); ends.add(new Point(0, plateBox.height()));
endM = Converters.vector_Point2f_to_Mat(ends); endM = Converters.vector_Point2f_to_Mat(ends);
perspectiveTransform = Imgproc.getPerspectiveTransform(startM, endM); perspectiveTransform = Imgproc.getPerspectiveTransform(startM, endM);
Mat outputMat = new Mat((int)faceBox.height() , (int)faceBox.width(), CvType.CV_8UC4); Mat outputMat = new Mat((int)plateBox.height() , (int)plateBox.width(), CvType.CV_8UC4);
Imgproc.warpPerspective(image, outputMat, perspectiveTransform, new Size((int)faceBox.width(), (int)faceBox.height()), Imgproc.INTER_CUBIC); Imgproc.warpPerspective(image, outputMat, perspectiveTransform, new Size((int)plateBox.width(), (int)plateBox.height()), Imgproc.INTER_CUBIC);
return outputMat; return outputMat;
}finally { }finally {
if(null != endM){ if(null != endM){

111
open-anpr-core/src/main/java/com/visual/open/anpr/core/utils/MaskUtil.java

@ -1,111 +0,0 @@
package com.visual.open.anpr.core.utils;
import com.visual.face.search.core.domain.FaceInfo;
import com.visual.face.search.core.domain.ImageMat;
import org.opencv.core.*;
import org.opencv.imgproc.Imgproc;
import java.util.ArrayList;
import java.util.List;
public class MaskUtil {
/**添加遮罩层所需要的索引号:InsightCoordFaceKeyPoint**/
private static int [] MASK_106_IST_ROUND_INDEX = new int[]{
1,9,10,11,12,13,14,15,16,2,3,4,5,6,7,8,0,
24,23,22,21,20,19,18,32,31,30,29,28,27,26,25,17,
101,105,104,103,102,50,51,49,48,43
};
/**
* 添加遮罩层
* @param image 原始图像
* @param pts 指定不不需要填充的区域
* @param release 是否释放参数image
* @return
*/
public static Mat mask(Mat image, List<MatOfPoint> pts, boolean release){
Mat pattern = null;
try {
pattern = MatOfPoint.zeros(image.size(), CvType.CV_8U);
Imgproc.fillPoly(pattern, pts, new Scalar(1,1,1));
Mat dst = new Mat();
image.copyTo(dst, pattern);
return dst;
}finally {
if(null != pattern){
pattern.release();
}
if(release && null != pts){
for(MatOfPoint pt : pts){
pt.release();
}
}
if(release && null != image){
image.release();
}
}
}
/**
* 添加遮罩层
* @param image 原始图像
* @param fillPoints 指定不不需要填充的区域的点
* @param release 是否释放参数image
* @return
*/
public static Mat mask(Mat image, Point[] fillPoints, boolean release){
List<MatOfPoint> pts = null;
try {
pts = new ArrayList<>();
pts.add(new MatOfPoint(fillPoints));
return mask(image, pts, false);
}finally {
if(null != pts){
for(MatOfPoint pt : pts){
pt.release();
}
}
if(release && null != image){
image.release();
}
}
}
/**
* 添加遮罩层:InsightCoordFaceKeyPoint
* @param image 原始图像
* @param points 人脸标记点
* @param release 是否释放参数image
* @return
*/
public static Mat maskFor106InsightCoordModel(Mat image, FaceInfo.Points points, boolean release){
try {
Point[] fillPoints = PointUtil.convert(points.select(MASK_106_IST_ROUND_INDEX));
return mask(image, fillPoints, false);
}finally {
if(release && null != image){
image.release();
}
}
}
/**
* 添加遮罩层:InsightCoordFaceKeyPoint
* @param image 原始图像
* @param points 人脸标记点
* @param release 是否释放参数image
* @return
*/
public static ImageMat maskFor106InsightCoordModel(ImageMat image, FaceInfo.Points points, boolean release){
try {
Mat mat = maskFor106InsightCoordModel(image.toCvMat(), points, false);
return ImageMat.fromCVMat(mat);
}finally {
if(release && null != image){
image.release();
}
}
}
}

39
open-anpr-core/src/main/java/com/visual/open/anpr/core/utils/PointUtil.java

@ -1,39 +0,0 @@
package com.visual.open.anpr.core.utils;
import com.visual.face.search.core.domain.FaceInfo;
import org.opencv.core.Point;
public class PointUtil {
/**
* 转换点对象
* @param point
* @return
*/
public static FaceInfo.Point convert(Point point){
return FaceInfo.Point.build((float)point.x, (float)point.y);
}
/**
* 转换点对象
* @param point
* @return
*/
public static Point convert(FaceInfo.Point point){
return new Point(point.x, point.y);
}
/**
* 转换点对象
* @param points
* @return
*/
public static Point[] convert(FaceInfo.Points points){
Point[] result = new Point[points.size()];
for(int i=0; i< points.size(); i++){
result[i] = convert(points.get(i));
}
return result;
}
}

15
open-anpr-core/src/main/java/com/visual/open/anpr/core/utils/ReleaseUtil.java

@ -2,8 +2,7 @@ package com.visual.open.anpr.core.utils;
import ai.onnxruntime.OnnxTensor; import ai.onnxruntime.OnnxTensor;
import ai.onnxruntime.OrtSession; import ai.onnxruntime.OrtSession;
import com.visual.face.search.core.domain.ImageMat; import com.visual.open.anpr.core.domain.ImageMat;
import com.visual.face.search.core.domain.Mats;
import org.opencv.core.Mat; import org.opencv.core.Mat;
public class ReleaseUtil { public class ReleaseUtil {
@ -22,18 +21,6 @@ public class ReleaseUtil {
} }
} }
public static void release(Mats mats){
if(null == mats || mats.isEmpty()){
return;
}
try {
mats.release();
}catch (Exception e){
e.printStackTrace();
}finally {
mats = null;
}
}
public static void release(ImageMat ...imageMats){ public static void release(ImageMat ...imageMats){
for(ImageMat imageMat : imageMats){ for(ImageMat imageMat : imageMats){

4
open-anpr-core/src/main/java/com/visual/open/anpr/core/utils/Similarity.java

@ -2,7 +2,7 @@ package com.visual.open.anpr.core.utils;
import org.apache.commons.math3.linear.RealMatrix; import org.apache.commons.math3.linear.RealMatrix;
import static com.visual.face.search.core.utils.ArrayUtil.matrixNorm; import com.visual.open.anpr.core.utils.ArrayUtil;
public class Similarity { public class Similarity {
@ -66,7 +66,7 @@ public class Similarity {
RealMatrix rm1 = MathUtil.createMatrix(1, ArrayUtil.floatToDouble(leftVector)); RealMatrix rm1 = MathUtil.createMatrix(1, ArrayUtil.floatToDouble(leftVector));
RealMatrix rm2 = MathUtil.createMatrix(1, ArrayUtil.floatToDouble(rightVector)); RealMatrix rm2 = MathUtil.createMatrix(1, ArrayUtil.floatToDouble(rightVector));
RealMatrix num = rm1.multiply(rm2.transpose()); RealMatrix num = rm1.multiply(rm2.transpose());
double deco = matrixNorm(rm1.getData()) * matrixNorm(rm2.getData()); double deco = ArrayUtil.matrixNorm(rm1.getData()) * ArrayUtil.matrixNorm(rm2.getData());
double cos = num.getEntry(0, 0) / deco; double cos = num.getEntry(0, 0) / deco;
double sim = cos; double sim = cos;
if(cos >= 0.5){ if(cos >= 0.5){

Loading…
Cancel
Save