1 changed files with 285 additions and 0 deletions
			
			
		@ -0,0 +1,285 @@ | 
				
			|||||
 | 
					package com.visual.open.anpr.core.domain; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import java.io.Serializable; | 
				
			||||
 | 
					import java.util.ArrayList; | 
				
			||||
 | 
					import java.util.Arrays; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					public class PlateInfo implements Comparable<PlateInfo>, Serializable { | 
				
			||||
 | 
					    /**车牌分数**/ | 
				
			||||
 | 
					    public float score; | 
				
			||||
 | 
					    /**车牌旋转角度**/ | 
				
			||||
 | 
					    public float angle; | 
				
			||||
 | 
					    /**车牌框**/ | 
				
			||||
 | 
					    public PlateBox box; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    /** | 
				
			||||
 | 
					     * 构造函数 | 
				
			||||
 | 
					     * @param score     车牌分数 | 
				
			||||
 | 
					     * @param box       车牌框 | 
				
			||||
 | 
					     * @param angle     车牌旋转角度 | 
				
			||||
 | 
					     */ | 
				
			||||
 | 
					    private PlateInfo(float score, PlateBox box, float angle) { | 
				
			||||
 | 
					        this.score = score; | 
				
			||||
 | 
					        this.angle = angle; | 
				
			||||
 | 
					        this.box = box; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    /** | 
				
			||||
 | 
					     * 构造一个车牌信息 | 
				
			||||
 | 
					     * @param score     车牌分数 | 
				
			||||
 | 
					     * @param box       车牌框 | 
				
			||||
 | 
					     */ | 
				
			||||
 | 
					    public static PlateInfo build(float score, PlateBox box){ | 
				
			||||
 | 
					        return new PlateInfo(score, box, 0); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    /** | 
				
			||||
 | 
					     * 构造一个车牌信息 | 
				
			||||
 | 
					     * @param score     车牌分数 | 
				
			||||
 | 
					     * @param box       车牌框 | 
				
			||||
 | 
					     * @param angle     车牌旋转角度 | 
				
			||||
 | 
					     */ | 
				
			||||
 | 
					    public static PlateInfo build(float score, PlateBox box, float angle){ | 
				
			||||
 | 
					        return new PlateInfo(score, box, angle); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    /** | 
				
			||||
 | 
					     * 对车牌框进行旋转对应的角度 | 
				
			||||
 | 
					     * @return | 
				
			||||
 | 
					     */ | 
				
			||||
 | 
					    public PlateBox rotateFaceBox(){ | 
				
			||||
 | 
					        return this.box.rotate(this.angle); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @Override | 
				
			||||
 | 
					    public int compareTo(PlateInfo that) { | 
				
			||||
 | 
					        return Float.compare(that.score, this.score); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    /** | 
				
			||||
 | 
					     * 关键点 | 
				
			||||
 | 
					     */ | 
				
			||||
 | 
					    public static class Point implements Serializable { | 
				
			||||
 | 
					        /**坐标X的值**/ | 
				
			||||
 | 
					        public float x; | 
				
			||||
 | 
					        /**坐标Y的值**/ | 
				
			||||
 | 
					        public float y; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * 构造函数 | 
				
			||||
 | 
					         * @param x 坐标X的值 | 
				
			||||
 | 
					         * @param y 坐标Y的值 | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        private Point(float x, float y){ | 
				
			||||
 | 
					            this.x = x; | 
				
			||||
 | 
					            this.y = y; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * 构造一个点 | 
				
			||||
 | 
					         * @param x 坐标X的值 | 
				
			||||
 | 
					         * @param y 坐标Y的值 | 
				
			||||
 | 
					         * @return | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        public static Point build(float x, float y){ | 
				
			||||
 | 
					            return new Point(x, y); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * 对点进行中心旋转 | 
				
			||||
 | 
					         * @param center    中心点 | 
				
			||||
 | 
					         * @param angle     旋转角度 | 
				
			||||
 | 
					         * @return  旋转后的角 | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        public Point rotation(Point center, float angle){ | 
				
			||||
 | 
					            double k = Math.toRadians(angle); | 
				
			||||
 | 
					            float nx1 = (float) ((this.x - center.x) * Math.cos(k) + (this.y - center.y) * Math.sin(k) + center.x); | 
				
			||||
 | 
					            float ny1 = (float) (-(this.x - center.x) * Math.sin(k) + (this.y - center.y) * Math.cos(k) + center.y); | 
				
			||||
 | 
					            return new Point(nx1, ny1); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * 计算两点之间的距离 | 
				
			||||
 | 
					         * @param that  点 | 
				
			||||
 | 
					         * @return  距离 | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        public float distance(Point that){ | 
				
			||||
 | 
					            return (float) Math.sqrt(Math.pow((this.x-that.x), 2)+Math.pow((this.y-that.y), 2)); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    /** | 
				
			||||
 | 
					     * 标准坐标系下的车牌框 | 
				
			||||
 | 
					     */ | 
				
			||||
 | 
					    public static class PlateBox implements Serializable { | 
				
			||||
 | 
					        /**左上角坐标值**/ | 
				
			||||
 | 
					        public Point leftTop; | 
				
			||||
 | 
					        /**右上角坐标**/ | 
				
			||||
 | 
					        public Point rightTop; | 
				
			||||
 | 
					        /**右下角坐标**/ | 
				
			||||
 | 
					        public Point rightBottom; | 
				
			||||
 | 
					        /**左下角坐标**/ | 
				
			||||
 | 
					        public Point leftBottom; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * 构造函数 | 
				
			||||
 | 
					         * @param leftTop       左上角坐标值 | 
				
			||||
 | 
					         * @param rightTop      右上角坐标 | 
				
			||||
 | 
					         * @param rightBottom   右下角坐标 | 
				
			||||
 | 
					         * @param leftBottom    左下角坐标 | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        public PlateBox(Point leftTop, Point rightTop, Point rightBottom, Point leftBottom) { | 
				
			||||
 | 
					            this.leftTop = leftTop; | 
				
			||||
 | 
					            this.rightTop = rightTop; | 
				
			||||
 | 
					            this.rightBottom = rightBottom; | 
				
			||||
 | 
					            this.leftBottom = leftBottom; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * 构造函数 | 
				
			||||
 | 
					         * @param x1  左上角坐标X的值 | 
				
			||||
 | 
					         * @param y1  左上角坐标Y的值 | 
				
			||||
 | 
					         * @param x2  右下角坐标X的值 | 
				
			||||
 | 
					         * @param y2  右下角坐标Y的值 | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        private PlateBox(float x1, float y1, float x2, float y2){ | 
				
			||||
 | 
					            this.leftTop = Point.build(x1, y1); | 
				
			||||
 | 
					            this.rightTop = Point.build(x2, y1); | 
				
			||||
 | 
					            this.rightBottom = Point.build(x2, y2); | 
				
			||||
 | 
					            this.leftBottom = Point.build(x1, y2); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * 构造一个车牌框 | 
				
			||||
 | 
					         * @param x1  左上角坐标X的值 | 
				
			||||
 | 
					         * @param y1  左上角坐标Y的值 | 
				
			||||
 | 
					         * @param x2  右下角坐标X的值 | 
				
			||||
 | 
					         * @param y2  右下角坐标Y的值 | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        public static PlateBox build(float x1, float y1, float x2, float y2){ | 
				
			||||
 | 
					            return new PlateBox((int)x1,(int)y1,(int)x2,(int)y2); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * x的最小坐标 | 
				
			||||
 | 
					         * @return | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        public float x1(){ | 
				
			||||
 | 
					            return Math.min(Math.min(Math.min(leftTop.x, rightTop.x), rightBottom.x), leftBottom.x); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * y的最小坐标 | 
				
			||||
 | 
					         * @return | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        public float y1(){ | 
				
			||||
 | 
					            return Math.min(Math.min(Math.min(leftTop.y, rightTop.y), rightBottom.y), leftBottom.y); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * x的最大坐标 | 
				
			||||
 | 
					         * @return | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        public float x2(){ | 
				
			||||
 | 
					            return Math.max(Math.max(Math.max(leftTop.x, rightTop.x), rightBottom.x), leftBottom.x); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * y的最大坐标 | 
				
			||||
 | 
					         * @return | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        public float y2(){ | 
				
			||||
 | 
					            return Math.max(Math.max(Math.max(leftTop.y, rightTop.y), rightBottom.y), leftBottom.y); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * 判断当前的车牌框是否是标准的车牌框,即非旋转后的车牌框。 | 
				
			||||
 | 
					         * @return 否是标准的车牌框 | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        public boolean normal(){ | 
				
			||||
 | 
					            if((int)leftTop.x == (int)leftBottom.x && (int)leftTop.y == (int)rightTop.y){ | 
				
			||||
 | 
					                if((int)rightBottom.x == (int)rightTop.x && (int)rightBottom.y == (int)leftBottom.y){ | 
				
			||||
 | 
					                    return true; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            return false; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * 获取宽度 | 
				
			||||
 | 
					         * @return | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        public float width(){ | 
				
			||||
 | 
					            return (float) Math.sqrt(Math.pow((rightTop.x-leftTop.x), 2)+Math.pow((rightTop.y-leftTop.y), 2)); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * 获取高度 | 
				
			||||
 | 
					         * @return | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        public float height(){ | 
				
			||||
 | 
					            return (float) Math.sqrt(Math.pow((rightTop.x-rightBottom.x), 2)+Math.pow((rightTop.y-rightBottom.y), 2)); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * 获取面积 | 
				
			||||
 | 
					         * @return | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        public float area(){ | 
				
			||||
 | 
					            return this.width() * this.height(); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * 中心点坐标 | 
				
			||||
 | 
					         * @return | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        public Point center(){ | 
				
			||||
 | 
					            return Point.build((rightTop.x + leftBottom.x) / 2, (rightTop.y + leftBottom.y) / 2); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * 对车牌框进行旋转对应的角度 | 
				
			||||
 | 
					         * @param angle 旋转角 | 
				
			||||
 | 
					         * @return | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        public PlateBox rotate(float angle){ | 
				
			||||
 | 
					            Point center = this.center(); | 
				
			||||
 | 
					            Point rPoint1 = this.leftTop.rotation(center, angle); | 
				
			||||
 | 
					            Point rPoint2 = this.rightTop.rotation(center, angle); | 
				
			||||
 | 
					            Point rPoint3 = this.rightBottom.rotation(center, angle); | 
				
			||||
 | 
					            Point rPoint4 = this.leftBottom.rotation(center, angle); | 
				
			||||
 | 
					            return new PlateBox(rPoint1, rPoint2, rPoint3, rPoint4); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * 中心缩放 | 
				
			||||
 | 
					         * @param scale | 
				
			||||
 | 
					         * @return | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        public PlateBox scaling(float scale){ | 
				
			||||
 | 
					            //p1-p3
 | 
				
			||||
 | 
					            float length_p1_p3 = leftTop.distance(rightBottom); | 
				
			||||
 | 
					            float x_diff_p1_p3 = leftTop.x-rightBottom.x; | 
				
			||||
 | 
					            float y_diff_p1_p3 = leftTop.y-rightBottom.y; | 
				
			||||
 | 
					            float change_p1_p3 = length_p1_p3 * (1-scale); | 
				
			||||
 | 
					            float change_x_p1_p3 = change_p1_p3 * x_diff_p1_p3 / length_p1_p3 / 2; | 
				
			||||
 | 
					            float change_y_p1_p3 = change_p1_p3 * y_diff_p1_p3 / length_p1_p3 / 2; | 
				
			||||
 | 
					            //p2-p4
 | 
				
			||||
 | 
					            float length_p2_p4 = rightTop.distance(leftBottom); | 
				
			||||
 | 
					            float x_diff_p2_p4 = rightTop.x-leftBottom.x; | 
				
			||||
 | 
					            float y_diff_p2_p4 = rightTop.y-leftBottom.y; | 
				
			||||
 | 
					            float change_p2_p4 = length_p2_p4 * (1-scale); | 
				
			||||
 | 
					            float change_x_p2_p4 = change_p2_p4 * x_diff_p2_p4 / length_p2_p4 / 2; | 
				
			||||
 | 
					            float change_y_p2_p4 = change_p2_p4 * y_diff_p2_p4 / length_p2_p4 / 2; | 
				
			||||
 | 
					            //构造车牌框
 | 
				
			||||
 | 
					            return new PlateBox( | 
				
			||||
 | 
					                    new Point(leftTop.x - change_x_p1_p3,  leftTop.y - change_y_p1_p3), | 
				
			||||
 | 
					                    new Point(rightTop.x - change_x_p2_p4,  rightTop.y - change_y_p2_p4), | 
				
			||||
 | 
					                    new Point(rightBottom.x + change_x_p1_p3,  rightBottom.y + change_y_p1_p3), | 
				
			||||
 | 
					                    new Point(leftBottom.x + change_x_p2_p4,  leftBottom.y + change_y_p2_p4) | 
				
			||||
 | 
					            ); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue