From f11fbf4a274b14b6658c6efa83661a33170106a0 Mon Sep 17 00:00:00 2001 From: thenk008 <794757862@qq.com> Date: Tue, 26 May 2020 16:06:14 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=80=89=E5=8C=BA=E7=BC=A9?= =?UTF-8?q?=E5=B0=8F=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/wlld/MatrixTools/MatrixOperation.java | 46 ++++++++ .../wlld/imageRecognition/Convolution.java | 78 +++++++++++- .../org/wlld/imageRecognition/Operation.java | 26 ++-- .../wlld/imageRecognition/TempleConfig.java | 9 ++ .../org/wlld/imageRecognition/border/Knn.java | 111 +++++++++++++++++- src/test/java/coverTest/FoodTest.java | 39 ++++-- 6 files changed, 285 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/wlld/MatrixTools/MatrixOperation.java b/src/main/java/org/wlld/MatrixTools/MatrixOperation.java index 311b8e1..2c51f1b 100644 --- a/src/main/java/org/wlld/MatrixTools/MatrixOperation.java +++ b/src/main/java/org/wlld/MatrixTools/MatrixOperation.java @@ -3,6 +3,7 @@ package org.wlld.MatrixTools; import org.wlld.tools.ArithUtil; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; public class MatrixOperation { @@ -67,6 +68,27 @@ public class MatrixOperation { } } + public static double errorNub(Matrix matrix, Matrix avgMatrix, int excNub) throws Exception {//求均方误差 + int y = matrix.getY(); + if (matrix.isRowVector() && avgMatrix.isRowVector() && y == avgMatrix.getY()) { + double[] subAll = new double[y]; + for (int j = 0; j < y; j++) { + double mySelf = matrix.getNumber(0, j); + double avg = avgMatrix.getNumber(0, j); + double sub = Math.pow(avg - mySelf, 2); + subAll[j] = sub; + } + Arrays.sort(subAll); + double sigma = 0; + for (int i = 0; i < y - excNub; i++) { + sigma = sigma + subAll[i]; + } + return sigma / (y - excNub); + } else { + throw new Exception("this matrix is not rowVector or length different"); + } + } + public static Matrix pushVector(Matrix myMatrix, Matrix matrix, boolean addRow) throws Exception { //向一个矩阵里合并一个行向量或者列向量到矩阵行或者列的末尾 if (matrix.getX() == 1 || matrix.getY() == 1) { @@ -353,6 +375,22 @@ public class MatrixOperation { } } + public static Matrix matrixPointDiv(Matrix matrix1, Matrix matrix2) throws Exception {//矩阵点除 + int x = matrix1.getX(); + int y = matrix1.getY(); + Matrix matrix = new Matrix(x, y); + if (matrix2.getX() == x && matrix2.getY() == y) { + for (int i = 0; i < x; i++) { + for (int j = 0; j < y; j++) { + matrix.setNub(i, j, matrix1.getNumber(i, j) / matrix2.getNumber(i, j)); + } + } + } else { + throw new Exception("two matrix is not equals"); + } + return matrix; + } + public static Matrix mulMatrix(Matrix matrix1, Matrix matrix2) throws Exception {//矩阵相乘 if (matrix1.getY() == matrix2.getX()) { Matrix matrix = new Matrix(matrix1.getX(), matrix2.getY()); @@ -384,6 +422,14 @@ public class MatrixOperation { } } + public static void mathDiv(Matrix matrix, double nub) throws Exception {//矩阵数除 + for (int i = 0; i < matrix.getX(); i++) { + for (int j = 0; j < matrix.getY(); j++) { + matrix.setNub(i, j, matrix.getNumber(i, j) / nub); + } + } + } + //行向量转LIST public static List rowVectorToList(Matrix matrix) throws Exception { List list = new ArrayList<>(); diff --git a/src/main/java/org/wlld/imageRecognition/Convolution.java b/src/main/java/org/wlld/imageRecognition/Convolution.java index 5fa5a06..cb316c4 100644 --- a/src/main/java/org/wlld/imageRecognition/Convolution.java +++ b/src/main/java/org/wlld/imageRecognition/Convolution.java @@ -106,6 +106,82 @@ public class Convolution extends Frequency { return features; } + public void filtering(ThreeChannelMatrix threeChannelMatrix) throws Exception {//平滑滤波 + Matrix matrixR = threeChannelMatrix.getMatrixR(); + Matrix matrixG = threeChannelMatrix.getMatrixG(); + Matrix matrixB = threeChannelMatrix.getMatrixB(); + int x = matrixR.getX(); + int y = matrixR.getY(); + Matrix matrixRFilter = new Matrix(x, y);//滤波后的R通道 + Matrix matrixGFilter = new Matrix(x, y);//滤波后的G通道 + Matrix matrixBFilter = new Matrix(x, y);//滤波后的B通道 + int row = 0; + int column = 0; + for (int i = 0; i < x; i++) { + for (int j = 0; j < y; j++) { + double sigmaR = 0; + double sigmaG = 0; + double sigmaB = 0; + double nub = 0; + for (int t = 0; t < 8; t++) { + row = 0; + column = 0; + switch (t) { + case 0://上 + row = i - 1; + break; + case 1://左 + column = j - 1; + break; + case 2://下 + row = i + 1; + break; + case 3://右 + column = j + 1; + break; + case 4://左上 + column = j - 1; + row = i - 1; + break; + case 5://左下 + column = j - 1; + row = i + 1; + break; + case 6://右下 + column = j + 1; + row = i + 1; + break; + case 7://右上 + column = j + 1; + row = i - 1; + break; + } + if (row >= 0 && column >= 0 && row < x && column < y) { + double r = matrixR.getNumber(row, column); + double g = matrixG.getNumber(row, column); + double b = matrixB.getNumber(row, column); + sigmaR = sigmaR + r; + sigmaG = sigmaG + g; + sigmaB = sigmaB + b; + nub++; + } + } + double pixelR = sigmaR / nub; + double pixelG = sigmaG / nub; + double pixelB = sigmaB / nub; + matrixRFilter.setNub(i, j, pixelR); + matrixGFilter.setNub(i, j, pixelG); + matrixBFilter.setNub(i, j, pixelB); + } + } + Matrix rPic = MatrixOperation.matrixPointDiv(matrixR, matrixRFilter); + Matrix gPic = MatrixOperation.matrixPointDiv(matrixG, matrixGFilter); + Matrix bPic = MatrixOperation.matrixPointDiv(matrixB, matrixBFilter); + threeChannelMatrix.setMatrixR(rPic); + threeChannelMatrix.setMatrixG(gPic); + threeChannelMatrix.setMatrixB(bPic); + } + public List getCenterColor(ThreeChannelMatrix threeChannelMatrix, int poolSize, int sqNub) throws Exception { Matrix matrixR = threeChannelMatrix.getMatrixR(); Matrix matrixG = threeChannelMatrix.getMatrixG(); @@ -119,7 +195,7 @@ public class Convolution extends Frequency { MeanClustering meanClustering = new MeanClustering(sqNub); for (int i = 0; i < x; i++) { for (int j = 0; j < y; j++) { - double[] color = new double[]{matrixR.getNumber(i, j) / 255, matrixG.getNumber(i, j) / 255, matrixB.getNumber(i, j) / 255}; + double[] color = new double[]{matrixR.getNumber(i, j), matrixG.getNumber(i, j), matrixB.getNumber(i, j)}; meanClustering.setColor(color); } } diff --git a/src/main/java/org/wlld/imageRecognition/Operation.java b/src/main/java/org/wlld/imageRecognition/Operation.java index 794a8c2..3633970 100644 --- a/src/main/java/org/wlld/imageRecognition/Operation.java +++ b/src/main/java/org/wlld/imageRecognition/Operation.java @@ -26,14 +26,17 @@ public class Operation {//进行计算 private MatrixBack matrixBack = new MatrixBack(); private ImageBack imageBack = new ImageBack(); private OutBack outBack; + private int dif; public Operation(TempleConfig templeConfig) { this.templeConfig = templeConfig; + dif = templeConfig.getShrink(); } public Operation(TempleConfig templeConfig, OutBack outBack) { this.templeConfig = templeConfig; this.outBack = outBack; + dif = templeConfig.getShrink(); } public List convolution(Matrix matrix, Map tagging) throws Exception { @@ -59,20 +62,22 @@ public class Operation {//进行计算 public void colorStudy(ThreeChannelMatrix threeChannelMatrix, int tag, List specificationsList) throws Exception { Watershed watershed = new Watershed(threeChannelMatrix.getMatrixRGB(), specificationsList, templeConfig); - RegionBody regionBody = watershed.rainfall().get(0); - int minX = regionBody.getMinX(); - int minY = regionBody.getMinY(); - int maxX = regionBody.getMaxX(); - int maxY = regionBody.getMaxY(); + List regionBodies = watershed.rainfall(); + RegionBody regionBody = regionBodies.get(0); + int minX = regionBody.getMinX() + dif; + int minY = regionBody.getMinY() + dif; + int maxX = regionBody.getMaxX() - dif; + int maxY = regionBody.getMaxY() - dif; int xSize = maxX - minX; int ySize = maxY - minY; ThreeChannelMatrix threeChannelMatrix1 = convolution.getRegionMatrix(threeChannelMatrix, minX, minY, xSize, ySize); + // convolution.filtering(threeChannelMatrix1);//光照过滤 int times = templeConfig.getTimes(); for (int i = 0; i < times; i++) { List feature = convolution.getCenterColor(threeChannelMatrix1, templeConfig.getPoolSize(), templeConfig.getFeatureNub()); if (templeConfig.isShowLog()) { - System.out.println(feature); + System.out.println(tag + ":" + feature); } //System.out.println("====================================="); int classifier = templeConfig.getClassifier(); @@ -125,13 +130,14 @@ public class Operation {//进行计算 List regionList = watershed.rainfall(); for (RegionBody regionBody : regionList) { MaxPoint maxPoint = new MaxPoint(); - int minX = regionBody.getMinX(); - int minY = regionBody.getMinY(); - int maxX = regionBody.getMaxX(); - int maxY = regionBody.getMaxY(); + int minX = regionBody.getMinX() + dif; + int minY = regionBody.getMinY() + dif; + int maxX = regionBody.getMaxX() - dif; + int maxY = regionBody.getMaxY() - dif; int xSize = maxX - minX; int ySize = maxY - minY; ThreeChannelMatrix threeChannelMatrix1 = convolution.getRegionMatrix(threeChannelMatrix, minX, minY, xSize, ySize); + //convolution.filtering(threeChannelMatrix1);//光照过滤 List feature = convolution.getCenterColor(threeChannelMatrix1, templeConfig.getPoolSize(), templeConfig.getFeatureNub()); if (templeConfig.isShowLog()) { diff --git a/src/main/java/org/wlld/imageRecognition/TempleConfig.java b/src/main/java/org/wlld/imageRecognition/TempleConfig.java index b6be7ef..76eff94 100644 --- a/src/main/java/org/wlld/imageRecognition/TempleConfig.java +++ b/src/main/java/org/wlld/imageRecognition/TempleConfig.java @@ -67,6 +67,15 @@ public class TempleConfig { private Knn knn;//KNN分类器 private int knnNub = 7;//KNN投票人数 private int times = 10;//聚类循环次数 + private int shrink = 60;//收缩参数 + + public int getShrink() { + return shrink; + } + + public void setShrink(int shrink) { + this.shrink = shrink; + } public int getTimes() { return times; diff --git a/src/main/java/org/wlld/imageRecognition/border/Knn.java b/src/main/java/org/wlld/imageRecognition/border/Knn.java index 1c1d4bf..70fdcfd 100644 --- a/src/main/java/org/wlld/imageRecognition/border/Knn.java +++ b/src/main/java/org/wlld/imageRecognition/border/Knn.java @@ -3,10 +3,7 @@ package org.wlld.imageRecognition.border; import org.wlld.MatrixTools.Matrix; import org.wlld.MatrixTools.MatrixOperation; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class Knn {//KNN分类器 private Map> featureMap = new HashMap<>(); @@ -71,9 +68,109 @@ public class Knn {//KNN分类器 } } + public int getType2(Matrix vector) throws Exception { + Map map = new HashMap<>(); + double[] sub = new double[vector.getY()];//记录最小差 + for (int t = 0; t < sub.length; t++) { + sub[t] = -1; + } + int[] types = new int[vector.getY()];//记录每个位置的最小类别 + for (Map.Entry> entry : featureMap.entrySet()) { + int type = entry.getKey(); + List matrices = entry.getValue(); + double minDist = -1; + Matrix minMatrix = null; + for (Matrix matrix : matrices) { + double dist = MatrixOperation.getEDist(matrix, vector); + if (minDist > dist || minDist == -1) { + minDist = dist; + minMatrix = matrix; + } + } + map.put(type, minMatrix); + } + //从所有最小的里面选取三名最小的 + int[] ty = getTypes(vector); + System.out.println(Arrays.toString(ty)); + //从所有最小的里面选取 + for (Map.Entry entry : map.entrySet()) { + int type = entry.getKey(); + if (isLive(ty, type)) { + Matrix matrix = entry.getValue(); + setMin(matrix, types, sub, vector, type); + } + } + System.out.println("最小位置:" + Arrays.toString(types)); + Map typeMap = new HashMap<>(); + for (int i = 0; i < types.length; i++) { + int type = types[i]; + if (typeMap.containsKey(type)) { + typeMap.put(type, typeMap.get(type) + 1); + } else { + typeMap.put(type, 1); + } + } + int type = 0; + int max = 0; + for (Map.Entry entry : typeMap.entrySet()) { + int key = entry.getKey(); + int nub = entry.getValue(); + if (nub > max) { + max = nub; + type = key; + } + } + return type; + } + + private boolean isLive(int[] types, int type) { + boolean isLive = false; + for (int ty : types) { + if (ty == type) { + isLive = true; + break; + } + } + return isLive; + } + + private void setMin(Matrix matrix, int[] types, double[] sub, Matrix vector, int type) throws Exception { + int y = vector.getY(); + for (int j = 0; j < y; j++) { + double nub = vector.getNumber(0, j); + double myNub = matrix.getNumber(0, j); + double subs = sub[j]; + double cha = Math.abs(nub - myNub); + if (subs > cha || subs == -1) { + sub[j] = cha; + types[j] = type; + } + } + } + + public int[] getTypes(Matrix vector) throws Exception { + double[] dists = new double[nub]; + // System.out.println("测试:" + vector.getString()); + int[] types = new int[nub]; + for (int i = 0; i < nub; i++) { + dists[i] = -1; + } + for (Map.Entry> entry : featureMap.entrySet()) { + int type = entry.getKey(); + List matrices = entry.getValue(); + for (Matrix matrix : matrices) { + //double dist = MatrixOperation.errorNub(vector, matrix, 0); + double dist = MatrixOperation.getEDist(matrix, vector); + compare(dists, types, dist, type); + } + } + return types; + } + public int getType(Matrix vector) throws Exception {//识别分类 int ty = 0; double[] dists = new double[nub]; + // System.out.println("测试:" + vector.getString()); int[] types = new int[nub]; for (int i = 0; i < nub; i++) { dists[i] = -1; @@ -82,10 +179,12 @@ public class Knn {//KNN分类器 int type = entry.getKey(); List matrices = entry.getValue(); for (Matrix matrix : matrices) { - double dist = MatrixOperation.getEDist(matrix, vector); + double dist = MatrixOperation.errorNub(vector, matrix, 0); + // double dist = MatrixOperation.getEDist(matrix, vector); compare(dists, types, dist, type); } } + System.out.println(Arrays.toString(types)); Map map = new HashMap<>(); for (int i = 0; i < nub; i++) { int type = types[i]; @@ -101,9 +200,9 @@ public class Knn {//KNN分类器 int type = entry.getKey(); if (value > max) { ty = type; + max = value; } } return ty; } - } diff --git a/src/test/java/coverTest/FoodTest.java b/src/test/java/coverTest/FoodTest.java index 02eea5f..6b41d32 100644 --- a/src/test/java/coverTest/FoodTest.java +++ b/src/test/java/coverTest/FoodTest.java @@ -21,6 +21,21 @@ public class FoodTest { test(); } + public static void one(double[] test, double[] right, double[] wrong) { + int nub = 0; + for (int i = 0; i < test.length; i++) { + double test1 = test[i]; + double right1 = right[i]; + double wrong1 = wrong[i]; + double sub1 = Math.abs(ArithUtil.sub(test1, right1)); + double sub2 = Math.abs(ArithUtil.sub(test1, wrong1)); + if (sub1 > sub2) { + nub++; + } + } + System.out.println(nub); + } + public static void test2(TempleConfig templeConfig) throws Exception { //test(); System.out.println("开始测试"); @@ -32,8 +47,8 @@ public class FoodTest { Specifications specifications = new Specifications(); specifications.setMinWidth(250); specifications.setMinHeight(250); - specifications.setMaxWidth(700); - specifications.setMaxHeight(700); + specifications.setMaxWidth(750); + specifications.setMaxHeight(750); specificationsList.add(specifications); Operation operation = new Operation(templeConfig); for (int i = 1; i <= 28; i++) { @@ -53,17 +68,19 @@ public class FoodTest { TempleConfig templeConfig = new TempleConfig(); templeConfig.isShowLog(true);//是否打印日志 templeConfig.setMaxRain(320);//切割阈值 - templeConfig.setFeatureNub(4); + templeConfig.setFeatureNub(3); templeConfig.sethTh(0.88); - templeConfig.setKnnNub(7); + templeConfig.setKnnNub(3); templeConfig.setPoolSize(2); templeConfig.setRegionNub(200); - templeConfig.setTimes(10);//聚类数据增强 + templeConfig.setShrink(60); + templeConfig.setTimes(2);//聚类数据增强 templeConfig.setClassifier(Classifier.KNN); templeConfig.init(StudyPattern.Cover_Pattern, true, 400, 400, 3); return templeConfig; } + //[111.9524500835, 96.2916434651, 72.3613475459, 158.2808372317, 151.0848410842, 127.5929760594, 190.9981899048, 205.9760033099, 204.0868156116] public static void test() throws Exception { Picture picture = new Picture(); TempleConfig templeConfig = getTemple(); @@ -72,8 +89,8 @@ public class FoodTest { Specifications specifications = new Specifications(); specifications.setMinWidth(250); specifications.setMinHeight(250); - specifications.setMaxWidth(700); - specifications.setMaxHeight(700); + specifications.setMaxWidth(750); + specifications.setMaxHeight(750); specificationsList.add(specifications); for (int i = 1; i <= 10; i++) { ThreeChannelMatrix threeChannelMatrix1 = picture.getThreeMatrix("D:\\share\\cai\\a/a" + i + ".jpg"); @@ -82,12 +99,20 @@ public class FoodTest { ThreeChannelMatrix threeChannelMatrix4 = picture.getThreeMatrix("D:\\share\\cai\\d/d" + i + ".jpg"); ThreeChannelMatrix threeChannelMatrix5 = picture.getThreeMatrix("D:\\share\\cai\\e/e" + i + ".jpg"); ThreeChannelMatrix threeChannelMatrix6 = picture.getThreeMatrix("D:\\share\\cai\\f/f" + i + ".jpg"); + ThreeChannelMatrix threeChannelMatrix7 = picture.getThreeMatrix("D:\\share\\cai\\h/h" + i + ".jpg"); + ThreeChannelMatrix threeChannelMatrix8 = picture.getThreeMatrix("D:\\share\\cai\\i/i" + i + ".jpg"); + ThreeChannelMatrix threeChannelMatrix9 = picture.getThreeMatrix("D:\\share\\cai\\j/j" + i + ".jpg"); + ThreeChannelMatrix threeChannelMatrix10 = picture.getThreeMatrix("D:\\share\\cai\\k/k" + i + ".jpg"); operation.colorStudy(threeChannelMatrix1, 1, specificationsList); operation.colorStudy(threeChannelMatrix2, 2, specificationsList); operation.colorStudy(threeChannelMatrix3, 3, specificationsList); operation.colorStudy(threeChannelMatrix4, 4, specificationsList); operation.colorStudy(threeChannelMatrix5, 5, specificationsList); operation.colorStudy(threeChannelMatrix6, 6, specificationsList); + operation.colorStudy(threeChannelMatrix7, 7, specificationsList); + operation.colorStudy(threeChannelMatrix8, 8, specificationsList); + operation.colorStudy(threeChannelMatrix9, 9, specificationsList); + operation.colorStudy(threeChannelMatrix10, 10, specificationsList); System.out.println("=======================================" + i); }