diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 6aa88ff..d280c68 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -6,8 +6,8 @@ - + diff --git a/src/main/java/org/wlld/imageRecognition/KMatrix.java b/src/main/java/org/wlld/imageRecognition/KMatrix.java deleted file mode 100644 index 6a2ff48..0000000 --- a/src/main/java/org/wlld/imageRecognition/KMatrix.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.wlld.imageRecognition; - -import org.wlld.MatrixTools.Matrix; -import org.wlld.MatrixTools.MatrixOperation; -import org.wlld.tools.ArithUtil; - -/** - * @author lidapeng - * @description K均值聚类矩阵 - * @date 9:05 上午 2020/2/1 - */ -public class KMatrix { - private Matrix sigmaMatrix;//矩阵和 - private int nub;//加和次数 - private boolean isFinish = false;//是否结算 - - KMatrix(int x, int y) { - sigmaMatrix = new Matrix(x, y); - } - - public boolean isFinish() { - return isFinish; - } - - public void setFinish(boolean finish) { - isFinish = finish; - } - - public Matrix getSigmaMatrix() { - return sigmaMatrix; - } - - public double getEDist(Matrix matrix) throws Exception {//返回欧式距离 - if (isFinish && matrix.getX() == sigmaMatrix.getX() - && matrix.getY() == sigmaMatrix.getY()) { - double sigma = 0; - for (int i = 0; i < matrix.getX(); i++) { - for (int j = 0; j < matrix.getY(); j++) { - double sub = ArithUtil.sub(matrix.getNumber(i, j), sigmaMatrix.getNumber(i, j)); - sigma = ArithUtil.add(Math.pow(sub, 2), sigma); - } - } - sigma = Math.sqrt(sigma); - return sigma; - } else { - throw new Exception("K is not finish or matrix not equal"); - } - } - - public void addMatrix(Matrix matrix) throws Exception { - sigmaMatrix = MatrixOperation.add(sigmaMatrix, matrix); - nub++; - } - - public void getK() throws Exception {//结算K均值 - if (nub != 0) { - double aNub = ArithUtil.div(1, nub); - MatrixOperation.mathMul(sigmaMatrix, aNub); - isFinish = true; - } else { - throw new Exception("not value"); - } - } -} diff --git a/src/main/java/org/wlld/imageRecognition/Operation.java b/src/main/java/org/wlld/imageRecognition/Operation.java index 6519382..0733046 100644 --- a/src/main/java/org/wlld/imageRecognition/Operation.java +++ b/src/main/java/org/wlld/imageRecognition/Operation.java @@ -135,9 +135,9 @@ public class Operation {//进行计算 intoNerve2(eventId, frameBody.getMatrix(), templeConfig.getConvolutionNerveManager().getSensoryNerves(), false, -1, matrixBack); Matrix myMatrix = matrixBack.getMatrix(); - //卷积层输出即边框回归的输入的特征向量 + //卷积层输出即边框回归的输入的特征向量 TODO 这地有BUG 要改 frameBody.setEndMatrix(myMatrix); - int id = getClassificationId(myMatrix); + int id = getClassificationId2(myMatrix); frameBody.setId(id); } return toPosition(frameBodies, frame.getWidth(), frame.getHeight()); @@ -186,6 +186,21 @@ public class Operation {//进行计算 return map; } + private Matrix getBoxMatrix(Matrix matrix, Map boxMap) throws Exception { + Matrix positionMatrix = null; + double endDist = 0; + for (Map.Entry entry : boxMap.entrySet()) { + Box box = entry.getValue(); + Matrix boxMatrix = box.getMatrix(); + double dist = MatrixOperation.getEDist(matrix, boxMatrix); + if (endDist == 0 || dist < endDist) { + endDist = dist; + positionMatrix = box.getMatrixPosition(); + } + } + return positionMatrix; + } + //获得预测边框 private void getBox(FrameBody frameBody, int width, int height) throws Exception { if (templeConfig.isBoxReady()) { @@ -193,24 +208,16 @@ public class Operation {//进行计算 int id = frameBody.getId(); int x = frameBody.getX(); int y = frameBody.getY(); - Map borderBodyMap = templeConfig.getBorderBodyMap(); - BorderBody borderBody = borderBodyMap.get(id); - //都是列向量,将参数转化为行向量最后再加1 - Matrix xw = borderBody.getxW(); - Matrix yw = borderBody.getyW(); - Matrix hw = borderBody.gethW(); - Matrix ww = borderBody.getwW(); + KClustering kClustering = templeConfig.getkClusteringMap().get(id); + Map boxMap = kClustering.getPositionMap(); //将矩阵化为向量 matrix = MatrixOperation.matrixToVector(matrix, true); - //最后加一层池化 - matrix = MatrixOperation.getPoolVector(matrix); - //将参数矩阵的末尾填1 - matrix = MatrixOperation.push(matrix, 1, true); + Matrix positionMatrix = getBoxMatrix(matrix, boxMap); //锚点坐标及长宽预测值 - double tx = MatrixOperation.mulMatrix(matrix, xw).getNumber(0, 0); - double ty = MatrixOperation.mulMatrix(matrix, yw).getNumber(0, 0); - double th = MatrixOperation.mulMatrix(matrix, hw).getNumber(0, 0); - double tw = MatrixOperation.mulMatrix(matrix, ww).getNumber(0, 0); + double tx = positionMatrix.getNumber(0, 0); + double ty = positionMatrix.getNumber(0, 1); + double th = positionMatrix.getNumber(0, 3); + double tw = positionMatrix.getNumber(0, 2); //修正相对位置 double realX = ArithUtil.add(ArithUtil.mul(tx, height), x); double realY = ArithUtil.add(ArithUtil.mul(ty, width), y); @@ -304,22 +311,6 @@ public class Operation {//进行计算 return id; } - private int getClassificationId(Matrix myMatrix) throws Exception { - int id = 0; - double distEnd = 0; - Map kMatrixMap = templeConfig.getkMatrixMap(); - for (Map.Entry entry : kMatrixMap.entrySet()) { - int key = entry.getKey(); - KMatrix kMatrix = entry.getValue(); - double dist = kMatrix.getEDist(myMatrix); - if (distEnd == 0 || dist < distEnd) { - id = key; - distEnd = dist; - } - } - return id; - } - private List sub(Matrix matrix) throws Exception {// List list = new ArrayList<>(); int x = matrix.getX() - 1; diff --git a/src/main/java/org/wlld/imageRecognition/TempleConfig.java b/src/main/java/org/wlld/imageRecognition/TempleConfig.java index 1b73514..1414069 100644 --- a/src/main/java/org/wlld/imageRecognition/TempleConfig.java +++ b/src/main/java/org/wlld/imageRecognition/TempleConfig.java @@ -5,9 +5,7 @@ import org.wlld.MatrixTools.MatrixOperation; import org.wlld.config.StudyPattern; import org.wlld.function.ReLu; import org.wlld.function.Sigmod; -import org.wlld.imageRecognition.border.BorderBody; -import org.wlld.imageRecognition.border.Frame; -import org.wlld.imageRecognition.border.LVQ; +import org.wlld.imageRecognition.border.*; import org.wlld.nerveCenter.NerveManager; import org.wlld.nerveEntity.ModelParameter; import org.wlld.nerveEntity.SensoryNerve; @@ -29,14 +27,18 @@ public class TempleConfig { private int classificationNub = 1;//分类的数量 private int studyPattern;//学习模式 private boolean isHavePosition = false;//是否需要锁定物体位置 - private Map borderBodyMap = new HashMap<>();//border特征集合 - private Map kMatrixMap = new HashMap<>();//K均值矩阵集合 private LVQ lvq; private Frame frame;//先验边框 private double th = 0.6;//标准阈值 private boolean boxReady = false;//边框已经学习完毕 private double iouTh = 0.5;//IOU阈值 private int lvqNub = 50;//lvq循环次数,默认50 + //边框聚类集合 + private Map kClusteringMap = new HashMap<>(); + + public Map getkClusteringMap() { + return kClusteringMap; + } public int getLvqNub() { return lvqNub; @@ -74,20 +76,6 @@ public class TempleConfig { this.frame = frame; } - public Map getBorderBodyMap() { - return borderBodyMap; - } - - public Map getkMatrixMap() { - return kMatrixMap; - } - - public void clustering() throws Exception {//进行聚类结算 - for (Map.Entry kMatrixEntry : kMatrixMap.entrySet()) { - kMatrixEntry.getValue().getK(); - } - } - public void startLvq() throws Exception {//进行量化 lvq.start(); } @@ -96,34 +84,15 @@ public class TempleConfig { return lvq; } - private void border(BorderBody borderBody) throws Exception { - Matrix parameter = borderBody.getX();//参数矩阵 - Matrix tx = borderBody.getTx(); - Matrix ty = borderBody.getTy(); - Matrix th = borderBody.getTh(); - Matrix tw = borderBody.getTw(); - borderBody.setxW(MatrixOperation.getLinearRegression(parameter, tx)); - borderBody.setyW(MatrixOperation.getLinearRegression(parameter, ty)); - borderBody.setwW(MatrixOperation.getLinearRegression(parameter, tw)); - borderBody.sethW(MatrixOperation.getLinearRegression(parameter, th)); - boxReady = true; - } - public void boxStudy() throws Exception {//边框回归 学习结束之后最后进行调用 - if (borderBodyMap.size() > 0) { - for (Map.Entry entry : borderBodyMap.entrySet()) { - border(entry.getValue()); + if (isHavePosition) { + for (Map.Entry entry : kClusteringMap.entrySet()) { + entry.getValue().start(); } - } else { - throw new Exception("boder not study"); } } - public void setBorderBodyMap(Map borderBodyMap) { - this.borderBodyMap = borderBodyMap; - } - public NerveManager getNerveManager() { return nerveManager; } @@ -152,6 +121,11 @@ public class TempleConfig { , int classificationNub) throws Exception {//初始化配置模板 this.classificationNub = classificationNub; this.studyPattern = studyPattern; + if (isHavePosition) { + for (int i = 1; i < classificationNub + 1; i++) { + kClusteringMap.put(i, new KClustering(20)); + } + } switch (studyPattern) { case StudyPattern.Speed_Pattern://速度学习模式 initModelVision(initPower, width, height); @@ -195,10 +169,8 @@ public class TempleConfig { //加载各识别分类的期望矩阵 matrixMap.put(0, new Matrix(height, width)); double nub = 10;//每个分类期望参数的跨度 - kMatrixMap.put(0, new KMatrix(height, width)); for (int k = 0; k < classificationNub; k++) { Matrix matrix = new Matrix(height, width);//初始化期望矩阵 - kMatrixMap.put(k + 1, new KMatrix(height, width)); double t = (k + 1) * nub;//期望矩阵的分类参数数值 for (int i = 0; i < height; i++) {//给期望矩阵注入期望参数 for (int j = 0; j < width - 1; j++) { @@ -241,19 +213,13 @@ public class TempleConfig { ModelParameter modelParameter1 = convolutionNerveManager.getModelParameter(); modelParameter.setDymNerveStudies(modelParameter1.getDymNerveStudies()); modelParameter.setDymOutNerveStudy(modelParameter1.getDymOutNerveStudy()); - Map> matrixMap = new HashMap<>(); - for (Map.Entry entry : kMatrixMap.entrySet()) { - List list = getFeatureList(entry.getValue().getSigmaMatrix()); - matrixMap.put(entry.getKey(), list); - } - modelParameter.setkMatrixList(matrixMap); + } else if (studyPattern == StudyPattern.Speed_Pattern) { ModelParameter modelParameter1 = nerveManager.getModelParameter(); modelParameter.setDepthNerves(modelParameter1.getDepthNerves()); modelParameter.setOutNevers(modelParameter1.getOutNevers()); } if (isHavePosition) {//存在边框学习模型参数 - modelParameter.setBorderBodyMap(borderBodyMap); modelParameter.setFrame(frame); } return modelParameter; @@ -293,24 +259,10 @@ public class TempleConfig { public void insertModel(ModelParameter modelParameter) throws Exception { if (studyPattern == StudyPattern.Accuracy_Pattern) { convolutionNerveManager.insertModelParameter(modelParameter); - Map> kMatrixs = modelParameter.getkMatrixList(); - if (kMatrixs != null && kMatrixs.size() == kMatrixMap.size()) { - for (Map.Entry entry : kMatrixMap.entrySet()) { - KMatrix kMatrix = entry.getValue(); - insertKMatrix(kMatrix.getSigmaMatrix(), kMatrixs.get(entry.getKey())); - kMatrix.setFinish(true); - } - } } else if (studyPattern == StudyPattern.Speed_Pattern) { nerveManager.insertModelParameter(modelParameter); } Frame frame = modelParameter.getFrame(); - Map borderBodyMap = modelParameter.getBorderBodyMap(); - if (frame != null && borderBodyMap != null && borderBodyMap.size() > 0) { - isHavePosition = true; - this.frame = frame; - this.borderBodyMap = borderBodyMap; - } } public void setCutThreshold(double cutThreshold) { diff --git a/src/main/java/org/wlld/imageRecognition/border/Border.java b/src/main/java/org/wlld/imageRecognition/border/Border.java index fcb12ee..e964625 100644 --- a/src/main/java/org/wlld/imageRecognition/border/Border.java +++ b/src/main/java/org/wlld/imageRecognition/border/Border.java @@ -48,51 +48,23 @@ public class Border { public void end(Matrix matrix, int id) throws Exception {//长宽 height = maxX - minX; width = maxY - minY; - Map borderBodyMap = templeConfig.getBorderBodyMap(); - BorderBody borderBody = borderBodyMap.get(id); - if (borderBody == null) { - borderBody = new BorderBody(); - borderBodyMap.put(id, borderBody); - } - //拿到参数矩阵 - Matrix matrixX = borderBody.getX(); - Matrix matrixTx = borderBody.getTx(); - Matrix matrixTy = borderBody.getTy(); - Matrix matrixTw = borderBody.getTw(); - Matrix matrixTh = borderBody.getTh(); + KClustering kClustering = templeConfig.getkClusteringMap().get(id); + Matrix positionMatrix = new Matrix(1, 4); //多元线性回归的四个输出值 double tx = ArithUtil.div(minX, modelHeight); double ty = ArithUtil.div(minY, modelWidth); double tw = Math.log(ArithUtil.div(width, modelWidth)); double th = Math.log(ArithUtil.div(height, modelHeight)); + Box box = new Box(); //进行参数汇集 矩阵转化为行向量 matrix = MatrixOperation.matrixToVector(matrix, true); - //最后给一层池化层 - matrix = MatrixOperation.getPoolVector(matrix); - //将参数矩阵的末尾填1 - matrix = MatrixOperation.push(matrix, 1, true); - if (matrixX == null) {//如果是第一次直接赋值 - matrixX = matrix; - matrixTx = new Matrix(1, 1); - matrixTy = new Matrix(1, 1); - matrixTw = new Matrix(1, 1); - matrixTh = new Matrix(1, 1); - matrixTx.setNub(0, 0, tx); - matrixTy.setNub(0, 0, ty); - matrixTw.setNub(0, 0, tw); - matrixTh.setNub(0, 0, th); - } else {//将新的参数矩阵添加到原来的末尾 - matrixX = MatrixOperation.pushVector(matrixX, matrix, true); - matrixTx = MatrixOperation.push(matrixTx, tx, false); - matrixTy = MatrixOperation.push(matrixTy, ty, false); - matrixTw = MatrixOperation.push(matrixTw, tw, false); - matrixTh = MatrixOperation.push(matrixTh, th, false); - } - borderBody.setX(matrixX); - borderBody.setTh(matrixTh); - borderBody.setTw(matrixTw); - borderBody.setTx(matrixTx); - borderBody.setTy(matrixTy); + positionMatrix.setNub(0, 0, tx); + positionMatrix.setNub(0, 1, ty); + positionMatrix.setNub(0, 2, tw); + positionMatrix.setNub(0, 3, th); + box.setMatrix(matrix); + box.setMatrixPosition(positionMatrix); + kClustering.setMatrixList(box); } } diff --git a/src/main/java/org/wlld/imageRecognition/border/BorderBody.java b/src/main/java/org/wlld/imageRecognition/border/BorderBody.java deleted file mode 100644 index c80e67a..0000000 --- a/src/main/java/org/wlld/imageRecognition/border/BorderBody.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.wlld.imageRecognition.border; - -import org.wlld.MatrixTools.Matrix; - -/** - * @author lidapeng - * @description - * - * @date 8:49 上午 2020/1/24 - */ -public class BorderBody { - private Matrix xW;//平移X权重 - private Matrix yW;//平移Y权重 - private Matrix wW;//缩放宽度权重 - private Matrix hW;//缩放高度权重 - private Matrix x;//参数矩阵 - private Matrix tx;//X轴偏移量 - private Matrix ty;//Y轴偏移量 - private Matrix tw;//W缩放量 - private Matrix th;//H缩放量 - - public Matrix getxW() { - return xW; - } - - public void setxW(Matrix xW) { - this.xW = xW; - } - - public Matrix getyW() { - return yW; - } - - public void setyW(Matrix yW) { - this.yW = yW; - } - - public Matrix getwW() { - return wW; - } - - public void setwW(Matrix wW) { - this.wW = wW; - } - - public Matrix gethW() { - return hW; - } - - public void sethW(Matrix hW) { - this.hW = hW; - } - - public Matrix getX() { - return x; - } - - public void setX(Matrix x) { - this.x = x; - } - - public Matrix getTx() { - return tx; - } - - public void setTx(Matrix tx) { - this.tx = tx; - } - - public Matrix getTy() { - return ty; - } - - public void setTy(Matrix ty) { - this.ty = ty; - } - - public Matrix getTw() { - return tw; - } - - public void setTw(Matrix tw) { - this.tw = tw; - } - - public Matrix getTh() { - return th; - } - - public void setTh(Matrix th) { - this.th = th; - } -} diff --git a/src/main/java/org/wlld/imageRecognition/border/Box.java b/src/main/java/org/wlld/imageRecognition/border/Box.java index fa6b630..ea6929f 100644 --- a/src/main/java/org/wlld/imageRecognition/border/Box.java +++ b/src/main/java/org/wlld/imageRecognition/border/Box.java @@ -9,7 +9,7 @@ import org.wlld.MatrixTools.Matrix; */ public class Box { private Matrix matrix;//特征向量 - private Matrix matrixFather;//坐标向量 + private Matrix matrixPosition;//坐标向量 public Matrix getMatrix() { return matrix; @@ -19,11 +19,11 @@ public class Box { this.matrix = matrix; } - public Matrix getMatrixFather() { - return matrixFather; + public Matrix getMatrixPosition() { + return matrixPosition; } - public void setMatrixFather(Matrix matrixFather) { - this.matrixFather = matrixFather; + public void setMatrixPosition(Matrix matrixPosition) { + this.matrixPosition = matrixPosition; } } diff --git a/src/main/java/org/wlld/imageRecognition/border/KClustering.java b/src/main/java/org/wlld/imageRecognition/border/KClustering.java index eefa921..03be10d 100644 --- a/src/main/java/org/wlld/imageRecognition/border/KClustering.java +++ b/src/main/java/org/wlld/imageRecognition/border/KClustering.java @@ -17,13 +17,14 @@ public class KClustering { private int speciesQuantity;//种类数量 private Matrix[] matrices;//均值K private Map> clusterMap = new HashMap<>();//簇 + private Map positionMap = new HashMap<>(); + private boolean isReady = false; - public Matrix[] getMatrices() { - return matrices; - } - - public Map> getClusterMap() { - return clusterMap; + public Map getPositionMap() throws Exception { + if (!isReady) { + throw new Exception("not ready"); + } + return positionMap; } public KClustering(int speciesQuantity) { @@ -76,6 +77,29 @@ public class KClustering { return matrices2; } + private Matrix averagePosition(List boxes) throws Exception { + double nub = ArithUtil.div(1, boxes.size()); + Matrix matrix = new Matrix(1, 4); + for (Box box : boxes) { + matrix = MatrixOperation.add(matrix, box.getMatrixPosition()); + } + MatrixOperation.mathMul(matrix, nub); + return matrix; + } + + private void position() throws Exception { + for (Map.Entry> entry : clusterMap.entrySet()) { + List boxList = entry.getValue(); + int key = entry.getKey(); + Box box = new Box(); + Matrix position = averagePosition(boxList); + Matrix kMatrix = matrices[key]; + box.setMatrix(kMatrix); + box.setMatrixPosition(position); + positionMap.put(key, box); + } + } + private void clear() { for (Map.Entry> entry : clusterMap.entrySet()) { entry.getValue().clear(); @@ -116,7 +140,8 @@ public class KClustering { while (!isEqual); //聚类结束,进行坐标均值矩阵计算 System.out.println("聚类循环次数:" + nub); - + position(); + isReady = true; } else { throw new Exception("matrixList number less than 2"); } diff --git a/src/main/java/org/wlld/nerveEntity/ModelParameter.java b/src/main/java/org/wlld/nerveEntity/ModelParameter.java index cf3eea8..6bf5b29 100644 --- a/src/main/java/org/wlld/nerveEntity/ModelParameter.java +++ b/src/main/java/org/wlld/nerveEntity/ModelParameter.java @@ -1,8 +1,5 @@ package org.wlld.nerveEntity; -import org.wlld.MatrixTools.Matrix; -import org.wlld.imageRecognition.KMatrix; -import org.wlld.imageRecognition.border.BorderBody; import org.wlld.imageRecognition.border.Frame; import java.util.ArrayList; @@ -21,26 +18,8 @@ public class ModelParameter { private List outNevers = new ArrayList<>();//输出神经元 private List dymNerveStudies = new ArrayList<>();//动态神经元隐层 private DymNerveStudy dymOutNerveStudy = new DymNerveStudy();//动态神经元输出层 - private Map borderBodyMap = new HashMap<>();//border特征集合 - private Map> kMatrixList = new HashMap<>();//K均值矩阵集合 private Frame frame;//先验边框 - public Map> getkMatrixList() { - return kMatrixList; - } - - public void setkMatrixList(Map> kMatrixList) { - this.kMatrixList = kMatrixList; - } - - public Map getBorderBodyMap() { - return borderBodyMap; - } - - public void setBorderBodyMap(Map borderBodyMap) { - this.borderBodyMap = borderBodyMap; - } - public Frame getFrame() { return frame; } diff --git a/src/test/java/org/wlld/MatrixTest.java b/src/test/java/org/wlld/MatrixTest.java index fbb7cf0..2469bf4 100644 --- a/src/test/java/org/wlld/MatrixTest.java +++ b/src/test/java/org/wlld/MatrixTest.java @@ -2,9 +2,6 @@ package org.wlld; import org.wlld.MatrixTools.Matrix; import org.wlld.MatrixTools.MatrixOperation; -import org.wlld.imageRecognition.border.BorderBody; - -import java.util.Random; /** * @author lidapeng