From f18b825d79091a874d30c5e9cd50c408d1cdf567 Mon Sep 17 00:00:00 2001 From: lidapeng <794757862@qq.com> Date: Sun, 25 Oct 2020 15:53:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B7=B1=E5=B1=82=E6=98=A0?= =?UTF-8?q?=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wlld/imageRecognition/Convolution.java | 21 +- .../org/wlld/imageRecognition/Operation.java | 77 +------- .../segmentation/DimensionMappingStudy.java | 182 ++++++++++++------ .../segmentation/FeatureMapping.java | 33 ++++ src/main/java/org/wlld/param/Food.java | 11 +- src/test/java/coverTest/FoodTest.java | 10 +- 6 files changed, 171 insertions(+), 163 deletions(-) diff --git a/src/main/java/org/wlld/imageRecognition/Convolution.java b/src/main/java/org/wlld/imageRecognition/Convolution.java index f01eab2..058570f 100644 --- a/src/main/java/org/wlld/imageRecognition/Convolution.java +++ b/src/main/java/org/wlld/imageRecognition/Convolution.java @@ -135,7 +135,7 @@ public class Convolution extends Frequency { } public List getCenterTexture(ThreeChannelMatrix threeChannelMatrix, int size, TempleConfig templeConfig - , int sqNub, boolean isStudy) throws Exception { + , int sqNub) throws Exception { MeanClustering meanClustering = new MeanClustering(sqNub, templeConfig, true); Matrix matrixR = threeChannelMatrix.getMatrixR(); Matrix matrixG = threeChannelMatrix.getMatrixG(); @@ -146,8 +146,8 @@ public class Convolution extends Frequency { //局部特征选区筛选 int nub = size * size; int twoNub = nub * 2; - for (int i = 0; i <= xn - size; i += 3) { - for (int j = 0; j <= yn - size; j += 3) { + for (int i = 0; i <= xn - size; i += 2) { + for (int j = 0; j <= yn - size; j += 2) { Matrix sonR = matrixR.getSonOfMatrix(i, j, size, size); Matrix sonG = matrixG.getSonOfMatrix(i, j, size, size); Matrix sonB = matrixB.getSonOfMatrix(i, j, size, size); @@ -184,9 +184,6 @@ public class Convolution extends Frequency { List features = new ArrayList<>(); for (int i = 0; i < sqNub; i++) { double[] rgb = rgbNorms.get(i).getRgb(); - if (!isStudy) { - rgb = rgbMapping(rgb, i, templeConfig); - } for (int j = 0; j < rgb.length; j++) { features.add(rgb[j]); } @@ -196,18 +193,6 @@ public class Convolution extends Frequency { return features; } - private double[] rgbMapping(double[] rgb, int index, TempleConfig templeConfig) {//进行映射 - double[] mapping = templeConfig.getFood().getMappingParameter(); - int size = rgb.length; - int allSize = mapping.length / 2; - double[] mappingFeature = new double[size]; - for (int i = 0; i < size; i++) { - int myIndex = size * index + i; - mappingFeature[i] = rgb[i] * mapping[myIndex] + mapping[allSize + myIndex]; - } - return mappingFeature; - } - private void normalization(Matrix matrix) throws Exception { for (int i = 0; i < matrix.getX(); i++) { for (int j = 0; j < matrix.getY(); j++) { diff --git a/src/main/java/org/wlld/imageRecognition/Operation.java b/src/main/java/org/wlld/imageRecognition/Operation.java index 3fa5093..0f5a584 100644 --- a/src/main/java/org/wlld/imageRecognition/Operation.java +++ b/src/main/java/org/wlld/imageRecognition/Operation.java @@ -7,10 +7,7 @@ import org.wlld.config.Classifier; import org.wlld.config.StudyPattern; import org.wlld.i.OutBack; import org.wlld.imageRecognition.border.*; -import org.wlld.imageRecognition.segmentation.RegionBody; -import org.wlld.imageRecognition.segmentation.RgbRegression; -import org.wlld.imageRecognition.segmentation.Specifications; -import org.wlld.imageRecognition.segmentation.Watershed; +import org.wlld.imageRecognition.segmentation.*; import org.wlld.nerveCenter.NerveManager; import org.wlld.nerveCenter.Normalization; import org.wlld.nerveEntity.SensoryNerve; @@ -91,40 +88,13 @@ public class Operation {//进行计算 int maxY = regionBody.getMaxY() - dif; int xSize = maxX - minX; int ySize = maxY - minY; - //convolution.imgNormalization(threeChannelMatrix); ThreeChannelMatrix threeChannelMatrix1 = convolution.getRegionMatrix(threeChannelMatrix, minX, minY, xSize, ySize); - // List feature = convolution.getCenterColor(threeChannelMatrix1, templeConfig, templeConfig.getFeatureNub()); - List feature = convolution.getCenterTexture(threeChannelMatrix1, templeConfig.getFood().getRegionSize(), templeConfig, templeConfig.getFeatureNub(), true); - if (templeConfig.isShowLog()) { - System.out.println(tag + ":" + feature); - } - int classifier = templeConfig.getClassifier(); - switch (classifier) { - case Classifier.DNN: - Map map = new HashMap<>(); - map.put(tag, 1.0); - if (templeConfig.getSensoryNerves().size() == templeConfig.getFeatureNub() * 3) { - intoDnnNetwork(1, feature, templeConfig.getSensoryNerves(), true, map, null); - } else { - throw new Exception("nerves number is not equal featureNub"); - } - break; - case Classifier.LVQ: - Matrix vector = MatrixOperation.listToRowVector(feature); - lvqStudy(tag, vector); - break; - case Classifier.VAvg: - Matrix vec = MatrixOperation.listToRowVector(feature); - avgStudy(tag, vec); - break; - case Classifier.KNN: - Matrix veck = MatrixOperation.listToRowVector(feature); - knnStudy(tag, veck); - break; - } - + List feature = convolution.getCenterTexture(threeChannelMatrix1, templeConfig.getFood().getRegionSize(), templeConfig, templeConfig.getFeatureNub()); + Knn knn = templeConfig.getFood().getDimensionMappingStudy().getKnn(); + knn.insertMatrix(MatrixOperation.listToRowVector(feature), tag); return regionBody; } else { + System.out.println("error=============================================error"); for (RegionBody regionBody : regionBodies) { int minX = regionBody.getMinX(); int minY = regionBody.getMinY(); @@ -133,6 +103,7 @@ public class Operation {//进行计算 System.out.println("异常:minX==" + minX + ",minY==" + minY + ",maxX==" + maxX + ",maxY==" + maxY + ",tag==" + tag + "url==" + url); } + System.out.println("error=============================================error"); throw new Exception("Parameter exception region size==" + regionBodies.size()); } } @@ -159,7 +130,6 @@ public class Operation {//进行计算 Watershed watershed = new Watershed(threeChannelMatrix, specificationsList, templeConfig); List regionList = watershed.rainfall(); for (RegionBody regionBody : regionList) { - MaxPoint maxPoint = new MaxPoint(); int minX = regionBody.getMinX() + dif; int minY = regionBody.getMinY() + dif; int maxX = regionBody.getMaxX() - dif; @@ -167,37 +137,10 @@ public class Operation {//进行计算 int xSize = maxX - minX; int ySize = maxY - minY; ThreeChannelMatrix threeChannelMatrix1 = convolution.getRegionMatrix(threeChannelMatrix, minX, minY, xSize, ySize); - //List feature = convolution.getCenterColor(threeChannelMatrix1, templeConfig, templeConfig.getFeatureNub()); - List feature = convolution.getCenterTexture(threeChannelMatrix1, templeConfig.getFood().getRegionSize(), templeConfig, templeConfig.getFeatureNub(), false); - - if (templeConfig.isShowLog()) { - System.out.println(feature); - } - int classifier = templeConfig.getClassifier(); - int id = 0; - switch (classifier) { - case Classifier.LVQ: - Matrix myMatrix = MatrixOperation.listToRowVector(feature); - id = getIdByLVQ(myMatrix); - break; - case Classifier.DNN: - if (templeConfig.getSensoryNerves().size() == templeConfig.getFeatureNub() * 3) { - intoDnnNetwork(IdCreator.get().nextId(), feature, templeConfig.getSensoryNerves(), false, null, maxPoint); - id = maxPoint.getId(); - } else { - throw new Exception("nerves number is not equal featureNub"); - } - break; - case Classifier.VAvg: - Matrix myMatrix1 = MatrixOperation.listToRowVector(feature); - id = getIdByVag(myMatrix1); - break; - case Classifier.KNN: - Matrix myMatrix2 = MatrixOperation.listToRowVector(feature); - Knn knn = templeConfig.getKnn(); - id = knn.getType(myMatrix2); - break; - } + List feature = convolution.getCenterTexture(threeChannelMatrix1, templeConfig.getFood().getRegionSize(), templeConfig, templeConfig.getFeatureNub()); + Matrix myMatrix2 = MatrixOperation.listToRowVector(feature); + DimensionMappingStudy dimensionMappingStudy = templeConfig.getFood().getDimensionMappingStudy(); + int id = dimensionMappingStudy.toClassification(myMatrix2); regionBody.setType(id); System.out.println("类别" + id); } diff --git a/src/main/java/org/wlld/imageRecognition/segmentation/DimensionMappingStudy.java b/src/main/java/org/wlld/imageRecognition/segmentation/DimensionMappingStudy.java index 04eab49..2c2a98f 100644 --- a/src/main/java/org/wlld/imageRecognition/segmentation/DimensionMappingStudy.java +++ b/src/main/java/org/wlld/imageRecognition/segmentation/DimensionMappingStudy.java @@ -1,9 +1,9 @@ package org.wlld.imageRecognition.segmentation; import org.wlld.MatrixTools.Matrix; -import org.wlld.i.PsoFunction; -import org.wlld.imageRecognition.RGBNorm; +import org.wlld.MatrixTools.MatrixOperation; import org.wlld.imageRecognition.TempleConfig; +import org.wlld.imageRecognition.border.Knn; import org.wlld.pso.PSO; import java.util.*; @@ -16,6 +16,11 @@ import java.util.*; * @Description 维度映射 */ public class DimensionMappingStudy { + private Knn knn = new Knn(1);//一个knn分类器,决定进这一层哪个类别 + private int id;//类别id + private Map deepMappingMap = new HashMap<>(); + private double[] mappingSigma;//映射层 + private double getDist(Matrix data1, Matrix data2) throws Exception { int size = data1.getY(); double sigma = 0; @@ -25,38 +30,17 @@ public class DimensionMappingStudy { return Math.sqrt(sigma); } - private double compareSame(List testFeatures) throws Exception {//比较同类找最小值 - int size = testFeatures.size(); - double max = 0; - for (int i = 0; i < size; i++) { - Matrix feature = testFeatures.get(i); - double min = -1; - for (int j = 0; j < size; j++) { - if (i != j) { - double dist = getDist(feature, testFeatures.get(j)); - if (min == -1 || dist < min) { - min = dist; - } - } - } - if (min > max) { - max = min; - } - } - return max; - } + class MinTypeSort implements Comparator { - private double compareDifferent(List featureSame, List featureDifferent) throws Exception { - double min = -1;//比较异类取最小值 - for (Matrix myFeature : featureSame) { - for (Matrix feature : featureDifferent) { - double dist = getDist(myFeature, feature); - if (min < 0 || dist < min) { - min = dist; - } + @Override + public int compare(MinType o1, MinType o2) { + if (o1.minDist < o2.minDist) { + return -1; + } else if (o1.minDist > o2.minDist) { + return 1; } + return 0; } - return min; } class MinType { @@ -64,54 +48,119 @@ public class DimensionMappingStudy { private int type; } - public void selfTest(TempleConfig templeConfig) throws Exception {//对模型数据进行自检测 - Map> featureMap = templeConfig.getKnn().getFeatureMap(); - Map maxMap = new HashMap<>();//保存与该类别最大间距 - Map> minMap = new HashMap<>();//保存与该类别最相似的类别,及距离值 - for (Map.Entry> entry : featureMap.entrySet()) { - int key = entry.getKey(); - List minTypes = new ArrayList<>(); - List myFeatures = entry.getValue(); - double sameMax = compareSame(myFeatures);//同类之间的最大值 - maxMap.put(key, sameMax); - for (Map.Entry> entry2 : featureMap.entrySet()) { - int testKey = entry2.getKey(); - if (testKey != key) {//找出最小距离 - List features = entry2.getValue(); - MinType minType = new MinType(); - double minDist = compareDifferent(myFeatures, features);//该类别的最小值 - if (minDist < sameMax) { + private double getSub(List featureSame, List featureDifferent) throws Exception { + double minSub = 0; + for (int i = 0; i < featureSame.size(); i++) { + Matrix sameFeature = featureSame.get(i); + double differentMin = -1;//与异类相比的最小值 + double sameMin = -1;//与同类相比的最小值 + for (int j = 0; j < featureDifferent.size(); j++) { + Matrix differentFeature = featureDifferent.get(j); + double dist = getDist(sameFeature, differentFeature); + if (differentMin < 0 || dist < differentMin) { + differentMin = dist; + } + } + for (int k = 0; k < featureSame.size(); k++) { + if (k != i) { + Matrix feature = featureSame.get(k); + double dist = getDist(sameFeature, feature); + if (sameMin < 0 || dist < sameMin) { + sameMin = dist; + } + } + } + double sub = differentMin - sameMin;//异类距离与同类距离的差距,选出其中最小的 + if (i == 0) { + minSub = sub; + } else if (sub < minSub) { + minSub = sub; + } + } + return minSub; + } + + private void nextDeep(TempleConfig templeConfig) throws Exception {//对模型数据进行自检测 + Map> featureMap = knn.getFeatureMap(); + int nub = featureMap.size() / 2; + if (nub > 1) { + MinTypeSort minTypeSort = new MinTypeSort(); + Map> minMap = new HashMap<>();//保存与该类别最相似的类别,及距离值 + for (Map.Entry> entry : featureMap.entrySet()) { + int key = entry.getKey(); + List minTypes = new ArrayList<>(); + List myFeatures = entry.getValue(); + for (Map.Entry> entry2 : featureMap.entrySet()) { + int testKey = entry2.getKey(); + if (testKey != key) {//找出最小距离 + List features = entry2.getValue(); + MinType minType = new MinType(); + double minDist = getSub(myFeatures, features); minType.minDist = minDist; minType.type = testKey; minTypes.add(minType); } } + Collections.sort(minTypes, minTypeSort); + int len = 0; + for (int i = 0; i < minTypes.size(); i++) { + if (minTypes.get(i).minDist < 0) { + len++; + } else { + break; + } + } + if (len < nub) { + minTypes = minTypes.subList(0, nub); + } else { + minTypes = minTypes.subList(0, len); + } + minMap.put(key, minTypes); } - minMap.put(key, minTypes); - } - for (Map.Entry entry : maxMap.entrySet()) { - int key = entry.getKey(); - double maxValue = entry.getValue(); - System.out.println("============================================="); - System.out.println("类别:" + key + ",最大类间距为:" + maxValue); - List minTypes = minMap.get(key); - for (int i = 0; i < minTypes.size(); i++) { - MinType minType = minTypes.get(i); - System.out.println("相近类:" + minType.type + ",最小类间距为:" + minType.minDist); + for (Map.Entry> entry : minMap.entrySet()) { + if (nub == 2 || nub == 3) { + System.out.println("类别===============================" + entry.getKey()); + } + List minTypeList = entry.getValue(); + DimensionMappingStudy dimensionMappingStudy = new DimensionMappingStudy(); + Knn myKnn = dimensionMappingStudy.getKnn(); + for (MinType minType : minTypeList) { + if (nub == 2 || nub == 3) { + System.out.println("type==" + minType.type + ",dist==" + minType.minDist); + } + List featureList = featureMap.get(minType.type); + for (Matrix matrix : featureList) { + myKnn.insertMatrix(matrix, minType.type); + } + } + deepMappingMap.put(entry.getKey(), dimensionMappingStudy); } + for (Map.Entry entry : deepMappingMap.entrySet()) { + entry.getValue().start(templeConfig); + } + } + } + + public int toClassification(Matrix feature) throws Exception {//进行识别 先映射 + feature = mapping(feature, mappingSigma); + int type = knn.getType(feature); + if (deepMappingMap.size() > 0 && deepMappingMap.containsKey(type)) {//继续下一层 + return deepMappingMap.get(type).toClassification(feature); + } else {//返回最后结果 + return type; } } public void start(TempleConfig templeConfig) throws Exception { - Map> featureMap = templeConfig.getKnn().getFeatureMap(); + Map> featureMap = knn.getFeatureMap(); FeatureMapping featureMapping = new FeatureMapping(featureMap); int dimensionNub = templeConfig.getFeatureNub() * 3 * 2;//PSO维度 //创建粒子群 - PSO pso = new PSO(dimensionNub, null, null, 200, 100, - featureMapping, 0.4, 2, 2, true, 0.2, 0.01); + PSO pso = new PSO(dimensionNub, null, null, 500, 100, + featureMapping, 0.8, 2, 2, true, 0.2, 0.01); List mappings = pso.start(); int size = mappings.size(); - double[] mappingSigma = new double[dimensionNub]; + mappingSigma = new double[dimensionNub]; for (int i = 0; i < size; i++) { double[] mapping = mappings.get(i); for (int j = 0; j < mapping.length; j++) { @@ -121,9 +170,10 @@ public class DimensionMappingStudy { for (int i = 0; i < mappingSigma.length; i++) { mappingSigma[i] = mappingSigma[i] / size; } - templeConfig.getFood().setMappingParameter(mappingSigma); //还要把所有已存在的knn特征完成映射 featureMapping(featureMap, mappingSigma, templeConfig); + //进行下一次映射选择 + nextDeep(templeConfig); } private void featureMapping(Map> featureMap, double[] mapping @@ -150,4 +200,8 @@ public class DimensionMappingStudy { } return matrix; } + + public Knn getKnn() { + return knn; + } } diff --git a/src/main/java/org/wlld/imageRecognition/segmentation/FeatureMapping.java b/src/main/java/org/wlld/imageRecognition/segmentation/FeatureMapping.java index b71516a..fce16c6 100644 --- a/src/main/java/org/wlld/imageRecognition/segmentation/FeatureMapping.java +++ b/src/main/java/org/wlld/imageRecognition/segmentation/FeatureMapping.java @@ -80,6 +80,38 @@ public class FeatureMapping extends Frequency implements PsoFunction { return min; } + private double getSub(List featureSame, List featureDifferent) { + double minSub = 0; + for (int i = 0; i < featureSame.size(); i++) { + double[] sameFeature = featureSame.get(i); + double differentMin = -1;//与异类相比的最小值 + double sameMin = -1;//与同类相比的最小值 + for (int j = 0; j < featureDifferent.size(); j++) { + double[] differentFeature = featureDifferent.get(j); + double dist = getDist(sameFeature, differentFeature); + if (differentMin < 0 || dist < differentMin) { + differentMin = dist; + } + } + for (int k = 0; k < featureSame.size(); k++) { + if (k != i) { + double[] feature = featureSame.get(k); + double dist = getDist(sameFeature, feature); + if (sameMin < 0 || dist < sameMin) { + sameMin = dist; + } + } + } + double sub = differentMin - sameMin;//异类距离与同类距离的差距,选出其中最小的 + if (i == 0) { + minSub = sub; + } else if (sub < minSub) { + minSub = sub; + } + } + return minSub; + } + private double compareDist(Map> mapping) {//比较距离 double sigma = 0; for (Map.Entry> entry : mapping.entrySet()) { @@ -94,6 +126,7 @@ public class FeatureMapping extends Frequency implements PsoFunction { double sameMax = compareSame(myFeature);//同类最大值 double differentMin = compareDifferent(myFeature, featureDifferent);//异类最小值 double sub = differentMin - sameMax; + //double sub = getSub(myFeature, featureDifferent); sigma = sigma + sub; } return sigma; diff --git a/src/main/java/org/wlld/param/Food.java b/src/main/java/org/wlld/param/Food.java index 7c2adf6..ae2dda0 100644 --- a/src/main/java/org/wlld/param/Food.java +++ b/src/main/java/org/wlld/param/Food.java @@ -1,5 +1,6 @@ package org.wlld.param; +import org.wlld.imageRecognition.segmentation.DimensionMappingStudy; import org.wlld.imageRecognition.segmentation.KNerveManger; import org.wlld.imageRecognition.segmentation.RgbRegression; @@ -24,14 +25,10 @@ public class Food { private int step = 1;//特征取样步长 private int speciesNub = 24;//种类数 private KNerveManger kNerveManger; - private double[] mappingParameter;//特征映射 + private DimensionMappingStudy dimensionMappingStudy = new DimensionMappingStudy(); - public double[] getMappingParameter() { - return mappingParameter; - } - - public void setMappingParameter(double[] mappingParameter) { - this.mappingParameter = mappingParameter; + public DimensionMappingStudy getDimensionMappingStudy() { + return dimensionMappingStudy; } public KNerveManger getkNerveManger() { diff --git a/src/test/java/coverTest/FoodTest.java b/src/test/java/coverTest/FoodTest.java index a6f68f8..70d3837 100644 --- a/src/test/java/coverTest/FoodTest.java +++ b/src/test/java/coverTest/FoodTest.java @@ -98,11 +98,11 @@ public class FoodTest { specifications.setMaxWidth(600); specifications.setMaxHeight(600); specificationsList.add(specifications); - KNerveManger kNerveManger = templeConfig.getFood().getkNerveManger(); + //KNerveManger kNerveManger = templeConfig.getFood().getkNerveManger(); // ThreeChannelMatrix threeChannelMatrix = picture.getThreeMatrix("/Users/lidapeng/Desktop/myDocument/d.jpg"); // operation.setTray(threeChannelMatrix); String name = "/Users/lidapeng/Desktop/test/testOne/"; - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 4; i++) { System.out.println("轮数============================" + i); ThreeChannelMatrix threeChannelMatrix1 = picture.getThreeMatrix(name + "a" + i + ".jpg"); ThreeChannelMatrix threeChannelMatrix2 = picture.getThreeMatrix(name + "b" + i + ".jpg"); @@ -153,12 +153,8 @@ public class FoodTest { operation.colorStudy(threeChannelMatrix23, 23, specificationsList, name); operation.colorStudy(threeChannelMatrix24, 24, specificationsList, name); } - DimensionMappingStudy dimensionMappingStudy = new DimensionMappingStudy(); - //System.out.println("映射前检查========================"); - dimensionMappingStudy.selfTest(templeConfig);//检查 + DimensionMappingStudy dimensionMappingStudy = templeConfig.getFood().getDimensionMappingStudy(); dimensionMappingStudy.start(templeConfig);//完成映射 - System.out.println("映射后检查========================"); - dimensionMappingStudy.selfTest(templeConfig);//检查 //System.out.println("========================"); // kNerveManger.startStudy(); int i = 4;