From f39584e8712a83609359cbf3291a83ebd45dba06 Mon Sep 17 00:00:00 2001 From: diven Date: Tue, 17 Jan 2023 15:05:16 +0800 Subject: [PATCH] init --- .../core/models/PaddlePlateDetection.java | 230 ------------------ .../core/models/PaddlePlateDetectionTest.java | 90 ------- 2 files changed, 320 deletions(-) delete mode 100644 open-anpr-core/src/main/java/com/visual/open/anpr/core/models/PaddlePlateDetection.java delete mode 100644 open-anpr-core/src/test/java/com/visual/open/anpr/core/models/PaddlePlateDetectionTest.java diff --git a/open-anpr-core/src/main/java/com/visual/open/anpr/core/models/PaddlePlateDetection.java b/open-anpr-core/src/main/java/com/visual/open/anpr/core/models/PaddlePlateDetection.java deleted file mode 100644 index 6635818..0000000 --- a/open-anpr-core/src/main/java/com/visual/open/anpr/core/models/PaddlePlateDetection.java +++ /dev/null @@ -1,230 +0,0 @@ -package com.visual.open.anpr.core.models; - -import ai.onnxruntime.OnnxTensor; -import ai.onnxruntime.OrtSession; -import com.visual.open.anpr.core.base.BaseOnnxInfer; -import com.visual.open.anpr.core.base.PlateDetection; -import com.visual.open.anpr.core.clipper.Clipper; -import com.visual.open.anpr.core.clipper.ClipperOffset; -import com.visual.open.anpr.core.clipper.Path; -import com.visual.open.anpr.core.clipper.Paths; -import com.visual.open.anpr.core.domain.ImageMat; -import com.visual.open.anpr.core.domain.PlateInfo; -import com.visual.open.anpr.core.domain.Polygon; -import com.visual.open.anpr.core.utils.ReleaseUtil; -import org.opencv.core.*; -import org.opencv.imgproc.Imgproc; - -import java.util.*; -import java.util.stream.Collectors; - -public class PaddlePlateDetection extends BaseOnnxInfer implements PlateDetection { - - private float thresh=0.3f; - private float box_thresh=0.6f; - private int max_candidates=1000; - private float unclip_ratio=1.5f; - private float min_size = 3f; - - 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 inference(ImageMat image, float scoreTh, float iouTh, Map params) { - OnnxTensor tensor = null; - OrtSession.Result output = null; - ImageMat imageMat = image.clone(); - try { - //前置处理 - tensor = imageMat - .blobFromImageAndDoReleaseMat(1.0/255, this.mean, true) - .to4dFloatOnnxTensorAndNoReleaseMat(this.std,true); - //ONNX推理 - output = getSession().run(Collections.singletonMap(getInputName(), tensor)); - float[][][][] result = (float[][][][]) output.get(0).getValue(); - //模型后处理 - List plateInfos = new ArrayList<>(); - for (float[][] item : result[0]){ - List list = this.dbPostProcess(item, image.getWidth(), image.getHeight()); - if(!list.isEmpty()){ - plateInfos.addAll(list); - } - } - //返回 - return plateInfos; - }catch (Exception e){ - throw new RuntimeException(e); - }finally { - if(null != tensor){ - ReleaseUtil.release(tensor); - } - if(null != output){ - ReleaseUtil.release(output); - } - if(null != imageMat){ - ReleaseUtil.release(imageMat); - } - } - } - - /** - * 后处理 - * @param pred - * @param destWidth - * @param destHeight - * @return - */ - private List dbPostProcess(float[][] pred, int destWidth, int destHeight){ - //初始化Mat - Mat rawMat = Mat.zeros(pred.length,pred[0].length, CvType.CV_8UC1); - Mat maskMat = Mat.zeros(pred.length,pred[0].length, CvType.CV_8UC1); - int width = rawMat.width(); int height = rawMat.height(); - //添加数据 - for(int i=0; i< pred.length; i++){ - for(int j=0; j= thresh ? 255 : 0); - } - } - //边缘提取 - final List points = new ArrayList<>(); - final Mat hierarchy = new Mat(); - Imgproc.findContours(maskMat, points, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); - //遍历边缘 - List list = new ArrayList<>(); - int numContours = Math.min(points.size(), max_candidates); - for(int i=0; i Double.valueOf(Math.floor(item.x)).intValue()).min().getAsInt(), 0, w-1); - int xmax = clip(Arrays.stream(box).mapToInt((item) -> Double.valueOf(Math.ceil(item.x)).intValue()).max().getAsInt(), 0, w-1); - int ymin = clip(Arrays.stream(box).mapToInt((item) -> Double.valueOf(Math.floor(item.y)).intValue()).min().getAsInt(), 0, h-1); - int ymax = clip(Arrays.stream(box).mapToInt((item) -> Double.valueOf(Math.ceil(item.y)).intValue()).max().getAsInt(), 0, h-1); - Mat mask = Mat.zeros(ymax - ymin + 1,xmax - xmin + 1, CvType.CV_8UC1); - //组织多边形的蒙版数据 - List boxPoints = Arrays.stream(box).map((item)-> new Point(item.x, item.y)).collect(Collectors.toList()); - List boxPointList = Arrays.stream(box).map((item)-> new Point(item.x-xmin, item.y-ymin)).collect(Collectors.toList()); - MatOfPoint matOfPoint = new MatOfPoint(); - matOfPoint.fromList(boxPointList); - List ptsoo = Collections.singletonList(matOfPoint); - //数据填充 - Imgproc.fillPoly(mask, ptsoo, Scalar.all(1)); - Scalar scalar = Core.mean(new Mat(rawMat, new Rect( xmin, ymin, xmax + 1 -xmin, ymax + 1-ymin)), mask); - float score = (float) scalar.val[0]; - if(this.box_thresh > score){ - continue; - } - //多边形的距离计算 - Polygon polygon = new Polygon(boxPoints); - double distance = polygon.getArea() * unclip_ratio / polygon.getLength(); - //线和多边形的裁剪和偏移 - Path path = new Path(); - for(Point u : boxPoints){ - path.add(new com.visual.open.anpr.core.clipper.Point.LongPoint((long) u.x, (long)u.y)); - } - Paths paths = new Paths(); - ClipperOffset offset = new ClipperOffset(); - offset.addPath(path, Clipper.JoinType.ROUND, Clipper.EndType.CLOSED_POLYGON); - offset.execute(paths, distance); - //重新获取边缘线 - MatOfPoint contour1 = new MatOfPoint(); - List poo= paths.get(0).stream().map(item -> new Point(item.getX(), item.getY())).collect(Collectors.toList()); - contour1.fromList(poo); - //重新提取边缘线 - PlateInfo res1 = getMiniBoxes(contour1); - if(res1.score < this.min_size+2){ - continue; - } - //添加一点偏移量 - int offsetWidth = (int) (res1.box.width() * 0.00f); - int offsetHeight = (int) (res1.box.height() * 0.00f); - //组装返回信息 - PlateInfo r = PlateInfo.build(score, PlateInfo.PlateBox.build( - PlateInfo.Point.build( - clip(Math.round(res1.box.leftTop.x / width * destWidth) - offsetWidth, 0, destWidth), - clip(Math.round(res1.box.leftTop.y / height * destHeight) - offsetHeight, 0, destHeight)), - PlateInfo.Point.build( - clip(Math.round(res1.box.rightTop.x / width * destWidth) + offsetWidth, 0, destWidth), - clip(Math.round(res1.box.rightTop.y / height * destHeight) - offsetHeight, 0, destHeight)), - PlateInfo.Point.build( - clip(Math.round(res1.box.rightBottom.x / width * destWidth) + offsetWidth, 0, destWidth), - clip(Math.round(res1.box.rightBottom.y / height * destHeight) + offsetHeight, 0, destHeight)), - PlateInfo.Point.build( - clip(Math.round(res1.box.leftBottom.x / width * destWidth) - offsetWidth, 0, destWidth), - clip(Math.round(res1.box.leftBottom.y / height * destHeight) + offsetHeight, 0, destHeight)) - )); - list.add(r); - } - - return list; - } - - - public PlateInfo getMiniBoxes(MatOfPoint contour){ - MatOfPoint2f pts = new MatOfPoint2f(); - pts.fromList(contour.toList()); - RotatedRect rect = Imgproc.minAreaRect(pts); - - Mat yyy = new Mat(); - Imgproc.boxPoints(rect, yyy); - - List cs = new ArrayList<>(); - for (int m=0; m< yyy.size().height; m++){ - Point ccc = new Point(yyy.get(m, 0)[0], yyy.get(m, 1)[0]); - cs.add(ccc); - } - Collections.sort(cs, Comparator.comparingDouble(o -> o.x)); - - int index_1 = 0; - int index_2 = 1; - int index_3 = 2; - int index_4 = 3; - - if(cs.get(1).y > cs.get(0).y){ - index_1 = 0; - index_4 = 1; - }else{ - index_1 = 1; - index_4 = 0; - } - - if(cs.get(3).y > cs.get(2).y){ - index_2 = 2; - index_3 = 3; - }else{ - index_2 = 3; - index_3 = 2; - } - - double sside = Math.min(rect.size.height, rect.size.width); - PlateInfo.PlateBox plateBox = PlateInfo.PlateBox.build( - PlateInfo.Point.build((float) cs.get(index_1).x, (float)cs.get(index_1).y), - PlateInfo.Point.build((float) cs.get(index_2).x, (float)cs.get(index_2).y), - PlateInfo.Point.build((float) cs.get(index_3).x, (float)cs.get(index_3).y), - PlateInfo.Point.build((float) cs.get(index_4).x, (float)cs.get(index_4).y) - ); - return PlateInfo.build((float)sside, plateBox); - } - - public static int clip(int value, int min, int max){ - if(value > max){ - return max; - } - if(value < min){ - return min; - } - return value; - } - -} diff --git a/open-anpr-core/src/test/java/com/visual/open/anpr/core/models/PaddlePlateDetectionTest.java b/open-anpr-core/src/test/java/com/visual/open/anpr/core/models/PaddlePlateDetectionTest.java deleted file mode 100644 index a310c87..0000000 --- a/open-anpr-core/src/test/java/com/visual/open/anpr/core/models/PaddlePlateDetectionTest.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.visual.open.anpr.core.models; - -import com.visual.open.anpr.core.domain.DrawImage; -import com.visual.open.anpr.core.domain.ImageMat; -import com.visual.open.anpr.core.domain.PlateInfo; -import org.opencv.imgcodecs.Imgcodecs; - -import java.awt.*; -import java.util.HashMap; -import java.util.List; - -public class PaddlePlateDetectionTest { - - public static void main(String[] args) { - PaddlePlateDetection detection = new PaddlePlateDetection("open-anpr-core/src/main/resources/models/model3.onnx", 1); - - String imagePath = "open-anpr-core/src/test/resources/images/image010.jpg"; - for(int wi=1; wi <=128; wi++){ - for(int wy=3; wy>=0;wy--){ - int width = wi * 32 - wy; - for(int hi=1; hi <=128; hi++) { - for (int hy = 3; hy >= 0; hy--) { - int height = hi * 32 - hy; - ImageMat imageMat = null; - try { - imageMat = ImageMat.fromImage(imagePath).resizeAndDoReleaseMat(width, height); - List plateInfos = detection.inference(imageMat, 1,1, new HashMap<>()); - System.out.println(plateInfos); - System.out.println("success:"+width+":"+height); - }catch (Throwable t){ - System.out.println("error:"+width+":"+height); - }finally { - if(imageMat != null){ - imageMat.release(); - } - } - } - } - } - } - - -// for(int w=351; w <=351; w++){ -// for(int h=351; h <=351; h++){ -// ImageMat imageMat = null; -// try { -// imageMat = ImageMat.fromImage(imagePath).resizeAndDoReleaseMat(w, h); -// List plateInfos = detection.inference(imageMat, 1,1, new HashMap<>()); -// System.out.println(plateInfos); -// System.out.println("success:"+w+":"+h); -// }catch (Throwable t){ -// System.out.println("error:"+w+":"+h); -// }finally { -// if(imageMat != null){ -// imageMat.release(); -// } -// } -// } -// } - - - - - -// String image1Path = "open-anpr-core/src/test/resources/images/imagetmp.jpg"; -// Imgcodecs.imwrite(image1Path, imageMat.toCvMat()); - - -// DrawImage drawImage = DrawImage.build(image1Path); -// for(PlateInfo plateInfo : plateInfos){ -// PlateInfo.Point [] points = plateInfo.box.toArray(); -// for(int i =0; i< points.length; i++){ -// if(i+1 == points.length){ -// drawImage.drawLine( -// new DrawImage.Point((int)points[i].x, (int)points[i].y), -// new DrawImage.Point((int)points[0].x, (int)points[0].y), -// 2, Color.RED -// ); -// }else{ -// drawImage.drawLine( -// new DrawImage.Point((int)points[i].x, (int)points[i].y), -// new DrawImage.Point((int)points[i+1].x, (int)points[i+1].y), -// 2, Color.RED -// ); -// } -// } -// } -// ImageMat.fromCVMat(drawImage.toMat()).imShow(); - } -}