Browse Source

init

master
divenswu 2 years ago
parent
commit
bff702c6b8
  1. 285
      open-anpr-core/src/main/java/com/visual/open/anpr/core/domain/PlateInfo.java

285
open-anpr-core/src/main/java/com/visual/open/anpr/core/domain/PlateInfo.java

@ -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…
Cancel
Save