diff --git a/easyAi.iml b/easyAi.iml
new file mode 100644
index 0000000..389499f
--- /dev/null
+++ b/easyAi.iml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
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..7f57be8 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);
}
}
@@ -269,7 +345,7 @@ public class Convolution extends Frequency {
return myMatrix;
}
- protected Matrix late(Matrix matrix, int size) throws Exception {//迟化处理
+ protected Matrix late(Matrix matrix, int size) throws Exception {//池化处理
int xn = matrix.getX();
int yn = matrix.getY();
int x = xn / size;//求导后矩阵的行数
diff --git a/src/main/java/org/wlld/imageRecognition/Operation.java b/src/main/java/org/wlld/imageRecognition/Operation.java
index 794a8c2..c7dfa6f 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()) {
@@ -812,6 +818,49 @@ public class Operation {//进行计算
return id;
}
+ public double isCover(ThreeChannelMatrix threeChannelMatrix) throws Exception {//固定背景覆盖率计算
+ ThreeChannelMatrix backGround = templeConfig.getBackGround();
+ double minCover = templeConfig.getMinCover();
+ double maxCover = templeConfig.getMaxCover();
+ double errorBack = templeConfig.getBackGroundError();
+ if (backGround != null && maxCover > minCover && errorBack >= 0 && errorBack <= 255) {
+ Matrix matrixR = threeChannelMatrix.getMatrixR();
+ Matrix matrixG = threeChannelMatrix.getMatrixG();
+ Matrix matrixB = threeChannelMatrix.getMatrixB();
+ Matrix matrixRBg = backGround.getMatrixR();
+ Matrix matrixGBg = backGround.getMatrixG();
+ Matrix matrixBBg = backGround.getMatrixB();
+ int x = matrixR.getX();
+ int y = matrixR.getY();
+ double size = x * y;
+ double cover = 0;
+ if (x == matrixRBg.getX() && y == matrixRBg.getY()) {
+ for (int i = 0; i < x; i++) {
+ for (int j = 0; j < y; j++) {
+ double rB = matrixRBg.getNumber(i, j);
+ double gB = matrixGBg.getNumber(i, j);
+ double bB = matrixBBg.getNumber(i, j);
+ double r = matrixR.getNumber(i, j);
+ double g = matrixG.getNumber(i, j);
+ double b = matrixB.getNumber(i, j);
+ double subR = Math.abs(r - rB);
+ double subG = Math.abs(g - gB);
+ double subB = Math.abs(b - bB);
+ double error = (subR + subB + subG) / 3;
+ if (error > errorBack) {
+ cover++;
+ }
+ }
+ }
+ return cover / size;
+ } else {
+ throw new Exception("Temple matrix is different");
+ }
+ } else {
+ throw new Exception("value is null");
+ }
+ }
+
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 b6be7ef..4862ff1 100644
--- a/src/main/java/org/wlld/imageRecognition/TempleConfig.java
+++ b/src/main/java/org/wlld/imageRecognition/TempleConfig.java
@@ -67,6 +67,51 @@ public class TempleConfig {
private Knn knn;//KNN分类器
private int knnNub = 7;//KNN投票人数
private int times = 10;//聚类循环次数
+ private int shrink = 60;//收缩参数
+ private ThreeChannelMatrix backGround;//背景面板
+ private double minCover;//覆盖下限
+ private double maxCover;//覆盖上限
+ private double backGroundError;//背景误差偏移量,0-255
+
+ public double getBackGroundError() {
+ return backGroundError;
+ }
+
+ public void setBackGroundError(double backGroundError) {
+ this.backGroundError = backGroundError;
+ }
+
+ public double getMinCover() {
+ return minCover;
+ }
+
+ public void setMinCover(double minCover) {
+ this.minCover = minCover;
+ }
+
+ public double getMaxCover() {
+ return maxCover;
+ }
+
+ public void setMaxCover(double maxCover) {
+ this.maxCover = maxCover;
+ }
+
+ public ThreeChannelMatrix getBackGround() {
+ return backGround;
+ }
+
+ public void setBackGround(ThreeChannelMatrix backGround) {
+ this.backGround = backGround;
+ }
+
+ 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..e830b02 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,12 +68,13 @@ 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;
@@ -72,8 +88,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 +98,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);
}