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