diff --git a/easyAi.iml b/easyAi.iml
deleted file mode 100644
index 389499f..0000000
--- a/easyAi.iml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/java/org/wlld/imageRecognition/Convolution.java b/src/main/java/org/wlld/imageRecognition/Convolution.java
index 8e9d8c9..c424b11 100644
--- a/src/main/java/org/wlld/imageRecognition/Convolution.java
+++ b/src/main/java/org/wlld/imageRecognition/Convolution.java
@@ -10,8 +10,7 @@ import org.wlld.imageRecognition.modelEntity.RegressionBody;
import org.wlld.tools.ArithUtil;
import org.wlld.tools.Frequency;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
/**
* @author lidapeng
@@ -19,6 +18,8 @@ import java.util.List;
* @date 9:23 上午 2020/1/2
*/
public class Convolution extends Frequency {
+ private MeanClustering meanClustering;
+
protected Matrix getFeatures(Matrix matrix, int maxNub, TempleConfig templeConfig
, int id) throws Exception {
boolean isFirst = true;
@@ -39,6 +40,88 @@ public class Convolution extends Frequency {
return matrix;
}
+ public void kc(ThreeChannelMatrix threeChannelMatrix, int size, int sqNub) throws Exception {
+ Matrix matrixR = threeChannelMatrix.getMatrixR();
+ Matrix matrixG = threeChannelMatrix.getMatrixG();
+ Matrix matrixB = threeChannelMatrix.getMatrixB();
+ matrixR = late(matrixR, size);
+ matrixG = late(matrixG, size);
+ matrixB = late(matrixB, size);
+ int x = matrixR.getX();
+ int y = matrixR.getY();
+ 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};
+ meanClustering.setColor(color);
+ }
+ }
+ meanClustering.start();
+ List rgbNorms = meanClustering.getMatrices();
+ double minNorm = 0;
+ int normSize = rgbNorms.size();
+ for (int i = 0; i < normSize; i++) {
+ RGBNorm rgbNorm = rgbNorms.get(i);
+ double[] rgb = rgbNorm.getRgb();
+ for (int j = 0; j < normSize; j++) {
+ if (j != i) {
+ double normSub = getEDist(rgb, rgbNorms.get(j).getRgb());
+ if (minNorm == 0 || normSub < minNorm) {
+ minNorm = normSub;
+ }
+ }
+ }
+ }
+ minNorm = ArithUtil.div(minNorm, 2);
+ System.out.println("min==" + minNorm);
+ }
+
+ private void checkImage(Matrix matrixR, Matrix matrixG, Matrix matrixB, double minNorm, int size) {
+ List> lists = new ArrayList<>();
+ int x = matrixR.getX() - size;//求导后矩阵的行数
+ int y = matrixR.getY() - size;//求导后矩阵的列数
+ for (int i = 0; i < x; i += size) {//遍历行
+ for (int j = 0; j < y; j += size) {//遍历每行的列
+ Matrix myMatrixR = matrixR.getSonOfMatrix(i, j, size, size);
+ Matrix myMatrixG = matrixG.getSonOfMatrix(i, j, size, size);
+ Matrix myMatrixB = matrixB.getSonOfMatrix(i, j, size, size);
+
+ }
+ }
+ }
+
+ private void getListFeature(Matrix matrixR, Matrix matrixG, Matrix matrixB, double minNorm) throws Exception {
+ int x = matrixR.getX();
+ int y = matrixR.getY();
+ Map map = new HashMap<>();
+ List rgbNormList = meanClustering.getMatrices();
+ 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};
+ int id = -1;
+ double feature = 0;
+ double minDist = 0;
+ for (int t = 0; t < rgbNormList.size(); t++) {
+ RGBNorm rgbNorm = rgbNormList.get(t);
+ double dist = getEDist(color, rgbNorm.getRgb());
+ if (minDist == 0 || dist < minDist) {
+ minDist = dist;
+ id = t;
+ }
+ }
+ if (minDist >= minNorm) {
+ id = -1;
+ }
+ if (id > -1) {
+ feature = rgbNormList.get(id).getNorm();
+ }
+ if (!map.containsKey(feature)) {
+ map.put(feature, 1);
+ }
+ }
+ }
+ }
+
public List> imageTrance(Matrix matrix, int size, int featureNub) throws Exception {//矩阵和卷积核大小
int xn = matrix.getX();
int yn = matrix.getY();
@@ -160,14 +243,18 @@ public class Convolution extends Frequency {
for (int j = 0; j < yn - size; j += size) {
Matrix matrix1 = matrix.getSonOfMatrix(i, j, size, size);
double maxNub = 0;
+ int n = size * size;
+ double sigma = 0;
for (int t = 0; t < matrix1.getX(); t++) {
for (int k = 0; k < matrix1.getY(); k++) {
double nub = matrix1.getNumber(t, k);
+ sigma = sigma + nub;
if (nub > maxNub) {
maxNub = nub;
}
}
}
+ maxNub = ArithUtil.div(sigma, n);
//迟化的最大值是 MAXNUB
myMatrix.setNub(i / size, j / size, maxNub);
}
diff --git a/src/main/java/org/wlld/imageRecognition/MeanClustering.java b/src/main/java/org/wlld/imageRecognition/MeanClustering.java
new file mode 100644
index 0000000..26c9177
--- /dev/null
+++ b/src/main/java/org/wlld/imageRecognition/MeanClustering.java
@@ -0,0 +1,96 @@
+package org.wlld.imageRecognition;
+
+import java.util.*;
+
+//K均值聚类
+public class MeanClustering {
+ private List matrixList = new ArrayList<>();//聚类集合
+ private int length;//向量长度(模型需要返回)
+ private int speciesQuantity;//种类数量(模型需要返回)
+ private List matrices = new ArrayList<>();//均值K模型(模型需要返回)
+
+ public List getMatrices() {
+ return matrices;
+ }
+
+ public MeanClustering(int speciesQuantity) {
+ this.speciesQuantity = speciesQuantity;//聚类的数量
+ }
+
+ public void setColor(double[] color) throws Exception {
+ if (matrixList.size() == 0) {
+ matrixList.add(color);
+ length = color.length;
+ } else {
+ if (length == color.length) {
+ matrixList.add(color);
+ } else {
+ throw new Exception("vector length is different");
+ }
+ }
+ }
+
+ private void averageMatrix() {
+ for (double[] rgb : matrixList) {//遍历当前集合
+ double min = -1;
+ int id = 0;
+ for (int i = 0; i < speciesQuantity; i++) {
+ RGBNorm rgbNorm = matrices.get(i);
+ double dist = rgbNorm.getEDist(rgb);
+ if (min == -1 || dist < min) {
+ min = dist;
+ id = i;
+ }
+ }
+ //进簇
+ RGBNorm rgbNorm = matrices.get(id);
+ rgbNorm.setColor(rgb);
+ }
+ //重新计算均值
+ for (RGBNorm rgbNorm : matrices) {
+ rgbNorm.norm();
+ }
+ }
+
+ private boolean isNext() {
+ boolean isNext = false;
+ for (RGBNorm rgbNorm : matrices) {
+ isNext = rgbNorm.compare();
+ if (isNext) {
+ break;
+ }
+ }
+ return isNext;
+ }
+
+ private void clear() {
+ for (RGBNorm rgbNorm : matrices) {
+ rgbNorm.clear();
+ }
+ }
+
+ public void start() throws Exception {//开始聚类
+ if (matrixList.size() > 1) {
+ Random random = new Random();
+ for (int i = 0; i < speciesQuantity; i++) {//初始化均值向量
+ int index = random.nextInt(matrixList.size());
+ double[] rgb = matrixList.get(index);
+ RGBNorm rgbNorm = new RGBNorm(rgb);
+ //要进行深度克隆
+ matrices.add(rgbNorm);
+ }
+ //进行两者的比较
+ boolean isNext;
+ do {
+ averageMatrix();
+ isNext = isNext();
+ if (isNext) {
+ clear();
+ }
+ }
+ while (isNext);
+ } else {
+ throw new Exception("matrixList number less than 2");
+ }
+ }
+}
diff --git a/src/main/java/org/wlld/imageRecognition/RGBNorm.java b/src/main/java/org/wlld/imageRecognition/RGBNorm.java
new file mode 100644
index 0000000..19b5c04
--- /dev/null
+++ b/src/main/java/org/wlld/imageRecognition/RGBNorm.java
@@ -0,0 +1,84 @@
+package org.wlld.imageRecognition;
+
+import org.wlld.tools.ArithUtil;
+
+import java.util.Arrays;
+
+public class RGBNorm {
+ private double[] rgbAll = new double[3];
+ private double norm;
+ private int nub;
+ private double[] rgb = new double[3];
+ private double[] rgbUp;
+
+ RGBNorm(double[] rgb) {
+ this.rgbUp = rgb;
+ }
+
+ public void syn() {
+ rgbUp = rgb;
+ }
+
+ public void clear() {
+ rgbAll = new double[3];
+ nub = 0;
+ for (int i = 0; i < rgb.length; i++) {
+ rgbUp[i] = rgb[i];
+ }
+ //System.out.println("clear==" + Arrays.toString(rgbUp));
+ }
+
+ public int getNub() {
+ return nub;
+ }
+
+ public boolean compare() {
+ boolean isNext = false;
+ for (int i = 0; i < rgb.length; i++) {
+ if (rgb[i] != rgbUp[i]) {
+ isNext = true;
+ break;
+ }
+ }
+ return isNext;
+ }
+
+ public double getEDist(double[] x) {
+ double[] y = new double[x.length];
+ for (int i = 0; i < y.length; i++) {
+ y[i] = x[i] - rgbUp[i];
+ }
+ double sigma = 0;
+ for (int i = 0; i < y.length; i++) {
+ sigma = sigma + Math.pow(y[i], 2);
+ }
+ return Math.sqrt(sigma);
+ }
+
+ public void setColor(double[] rgb) {
+ for (int i = 0; i < rgb.length; i++) {
+ rgbAll[i] = rgbAll[i] + rgb[i];
+ }
+ nub++;
+ }
+
+ public void norm() {//范长计算
+ double sigma = 0;
+ if (nub > 0) {
+ for (int i = 0; i < rgb.length; i++) {
+ double rgbc = ArithUtil.div(rgbAll[i], nub);
+ rgb[i] = rgbc;
+ sigma = sigma + Math.pow(rgbc, 2);
+ }
+ norm = Math.sqrt(sigma);
+ }
+ }
+
+ public double getNorm() {
+ return norm;
+ }
+
+ public double[] getRgb() {
+ return rgb;
+ }
+}
diff --git a/src/main/java/org/wlld/imageRecognition/border/KClustering.java b/src/main/java/org/wlld/imageRecognition/border/KClustering.java
index 69ad9f8..e73f4a4 100644
--- a/src/main/java/org/wlld/imageRecognition/border/KClustering.java
+++ b/src/main/java/org/wlld/imageRecognition/border/KClustering.java
@@ -60,7 +60,7 @@ public class KClustering {
}
public KClustering(int speciesQuantity) {
- this.speciesQuantity = speciesQuantity;
+ this.speciesQuantity = speciesQuantity;//聚类的数量
matrices = new Matrix[speciesQuantity];
for (int i = 0; i < speciesQuantity; i++) {
clusterMap.put(i, new ArrayList<>());
@@ -163,8 +163,7 @@ public class KClustering {
matrices[i] = matrixList.get(index).getMatrix();
}
//进行两者的比较
- boolean isEqual = false;
- int nub = 0;
+ boolean isEqual;
do {
Matrix[] matrices2 = averageMatrix();
isEqual = equals(matrices, matrices2);
@@ -172,7 +171,6 @@ public class KClustering {
matrices = matrices2;
clear();
}
- nub++;
}
while (!isEqual);
//聚类结束,进行坐标均值矩阵计算
diff --git a/src/main/java/org/wlld/imageRecognition/segmentation/ImageSegmentation.java b/src/main/java/org/wlld/imageRecognition/segmentation/ImageSegmentation.java
index eddc4df..44d85a0 100644
--- a/src/main/java/org/wlld/imageRecognition/segmentation/ImageSegmentation.java
+++ b/src/main/java/org/wlld/imageRecognition/segmentation/ImageSegmentation.java
@@ -1,6 +1,7 @@
package org.wlld.imageRecognition.segmentation;
import org.wlld.MatrixTools.Matrix;
+import org.wlld.imageRecognition.ThreeChannelMatrix;
import java.util.HashMap;
import java.util.Map;
@@ -11,14 +12,26 @@ import java.util.Map;
* @date 10:25 上午 2020/1/13
*/
public class ImageSegmentation {
- private Matrix regionMap;
- private Matrix matrix;
+ private Matrix matrixR;
+ private Matrix matrixG;
+ private Matrix matrixB;
private Map regionBodyList = new HashMap<>();
private int id = 1;
- public ImageSegmentation(Matrix matrix) {
- this.matrix = matrix;
- regionMap = new Matrix(matrix.getX(), matrix.getY());
+ public ImageSegmentation(ThreeChannelMatrix threeChannelMatrix) throws Exception {
+ matrixR = threeChannelMatrix.getMatrixR();
+ matrixG = threeChannelMatrix.getMatrixG();
+ matrixB = threeChannelMatrix.getMatrixB();
+ int x = matrixR.getX();
+ int y = matrixR.getY();
+ for (int i = 0; i < x; i++) {
+ for (int j = 0; j < y; j++) {
+ double r = matrixR.getNumber(i, j);
+ double g = matrixG.getNumber(i, j);
+ double b = matrixB.getNumber(i, j);
+
+ }
+ }
}
public int getMin(double[] array) {
@@ -33,106 +46,4 @@ public class ImageSegmentation {
return minIdx;
}
- private void connect(int x, int y) throws Exception {
- double self = matrix.getNumber(x, y);
- double rightPixel = matrix.getNumber(x, y + 1);
- double leftPixel = matrix.getNumber(x, y - 1);
- double bottomPixel = matrix.getNumber(x + 1, y);
- double topPixel = matrix.getNumber(x - 1, y);
-
- double right = Math.abs(rightPixel - self);
- double left = Math.abs(leftPixel - self);
- double bottom = Math.abs(bottomPixel - self);
- double top = Math.abs(topPixel - self);
- double[] array = new double[]{left, right, top, bottom};
- double[] pixelArray = new double[]{leftPixel, rightPixel, topPixel, bottomPixel};
- int minIndex = getMin(array);
- int i, j;
- switch (minIndex) {
- case 0:
- i = x;
- j = y - 1;
- break;
- case 1:
- i = x;
- j = y + 1;
- break;
- case 2:
- i = x - 1;
- j = y;
- break;
- case 3:
- i = x + 1;
- j = y;
- break;
- default:
- throw new IllegalStateException("Unexpected value: " + minIndex);
- }
- int type = (int) regionMap.getNumber(i, j);
- if (type > 0) {//有选区了
- RegionBody regionBody = regionBodyList.get(type);
- regionBody.insertPosition(x, y, regionMap);
- regionBody.setPixel(self);
- } else {//链接最小方向的节点没有属于任何区域
- RegionBody regionBody = new RegionBody(id);
- regionBody.insertPosition(x, y, regionMap);
- regionBody.insertPosition(i, j, regionMap);
- regionBody.setPixel(pixelArray[minIndex]);
- regionBody.setPixel(self);
- regionBodyList.put(id, regionBody);
- id++;
- }
- }
-
- public void createMST() throws Exception {
- int x = matrix.getX() - 1;
- int y = matrix.getY() - 1;
- for (int i = 1; i < x; i++) {
- for (int j = 1; j < y; j++) {
- if (regionMap.getNumber(i, j) == 0.0) {
- connect(i, j);
- }
- }
- }
- for (int i = 0; i < 3; i++) {
- mergeMSTX();
- }
- }
-
-
- private void mergeMSTX() throws Exception {//合并选区
- int x = matrix.getX() - 1;
- int y = matrix.getY() - 1;
- int now = (int) regionMap.getNumber(1, 1);
- int nowX = 1;
- int nowY = 1;
- for (int i = 1; i < x; i++) {
- for (int j = 1; j < y; j++) {
- int self = (int) regionMap.getNumber(i, j);
- if (now != self) {//遇到不同选区 区域NOW尝试与区域self合并
- double nowPoint = matrix.getNumber(nowX, nowY);
- double selfPoint = matrix.getNumber(i, j);
- RegionBody nowMST = regionBodyList.get(now);
- RegionBody selfMST = regionBodyList.get(self);
- double nowDiff = nowMST.getMaxDiff();
- double selfDiff = selfMST.getMaxDiff();
- double diff = Math.abs(nowPoint - selfPoint);//当前边的差异性
- double minDiff;
- if (nowDiff > selfDiff) {//差异性最小的是SELF
- minDiff = selfDiff;
- } else {//差异性最小的是NOW
- minDiff = nowDiff;
- }
- if (diff <= minDiff) {//进行合并
- nowMST.merge(selfMST, regionMap);
- regionBodyList.remove(self);
- } else {//不进行合并
- now = self;
- }
- }
- nowX = i;
- nowY = j;
- }
- }
- }
}
diff --git a/src/main/java/org/wlld/imageRecognition/segmentation/RegionBody.java b/src/main/java/org/wlld/imageRecognition/segmentation/RegionBody.java
index 5eb8ee4..1d14e2f 100644
--- a/src/main/java/org/wlld/imageRecognition/segmentation/RegionBody.java
+++ b/src/main/java/org/wlld/imageRecognition/segmentation/RegionBody.java
@@ -10,99 +10,5 @@ import java.util.List;
* @description 分区实体
*/
public class RegionBody {
- private int minX = -1;
- private int maxX = -1;
- private int minY = -1;
- private int maxY = -1;
- private int point = 0xFFF;
- private int bit = 4 * 3;
- private int id;//本区域主键
- private double minPixel = -1;//最小像素值
- private double maxPixel = 0;//最大像素值
- private List pixels = new ArrayList<>();
- public int getMinX() {
- return minX;
- }
-
- public int getMaxX() {
- return maxX;
- }
-
- public int getMinY() {
- return minY;
- }
-
- public int getMaxY() {
- return maxY;
- }
-
- RegionBody(int id) {
- this.id = id;
- }
-
- public double getMaxDiff() {
- return maxPixel - minPixel;
- }
-
- public int getHeight() {
- return maxX - minX;
- }
-
- public int getWidth() {
- return maxY - minY;
- }
-
- public void merge(RegionBody body, Matrix regionMap) throws Exception {//合并区域
- List myPixels = body.getPixels();
- setPixel(body.getMaxPixel());
- setPixel(body.getMinPixel());
- for (int pixel : myPixels) {
- int x = pixel >> bit;
- int y = pixel & point;
- insertPosition(x, y, regionMap);
- }
-
- }
-
- public void setPixel(double pixel) {
- if (pixel < minPixel || minPixel == -1) {
- minPixel = pixel;
- }
- if (pixel > maxPixel) {
- maxPixel = pixel;
- }
- }
-
- public void insertPosition(int x, int y, Matrix regionMap) throws Exception {
- if (x < minX || minX == -1) {
- minX = x;
- }
- if (y < minY || minY == -1) {
- minY = y;
- }
- if (x > maxX) {
- maxX = x;
- }
- if (y > maxY) {
- maxY = y;
- }
- //行在前,列在后
- int pixel = x << bit | y;
- pixels.add(pixel);
- //给区域地图中的像素分配区域ID
- regionMap.setNub(x, y, id);
- }
-
- public double getMinPixel() {
- return minPixel;
- }
-
- public double getMaxPixel() {
- return maxPixel;
- }
-
- public List getPixels() {
- return pixels;
- }
}
diff --git a/src/main/java/org/wlld/tools/Frequency.java b/src/main/java/org/wlld/tools/Frequency.java
index 938b3fe..aa4fa69 100644
--- a/src/main/java/org/wlld/tools/Frequency.java
+++ b/src/main/java/org/wlld/tools/Frequency.java
@@ -14,6 +14,18 @@ public abstract class Frequency {//统计频数
return allNub;
}
+ public double getEDist(double[] x1, double[] x2) {//返回两个等长数组之间的欧式距离
+ double[] y = new double[x1.length];
+ for (int i = 0; i < y.length; i++) {
+ y[i] = x1[i] - x2[i];
+ }
+ double sigma = 0;
+ for (int i = 0; i < y.length; i++) {
+ sigma = sigma + Math.pow(y[i], 2);
+ }
+ return Math.sqrt(sigma);
+ }
+
public double averageByList(List m) {//计算平均值
int len = m.size();
double allNub = 0;
diff --git a/src/test/java/coverTest/CoverTest.java b/src/test/java/coverTest/CoverTest.java
index ba0bc5c..761ddbd 100644
--- a/src/test/java/coverTest/CoverTest.java
+++ b/src/test/java/coverTest/CoverTest.java
@@ -7,12 +7,11 @@ import org.wlld.ModelData;
import org.wlld.config.RZ;
import org.wlld.config.StudyPattern;
import org.wlld.function.Sigmod;
-import org.wlld.imageRecognition.Operation;
-import org.wlld.imageRecognition.Picture;
-import org.wlld.imageRecognition.TempleConfig;
+import org.wlld.imageRecognition.*;
import org.wlld.nerveEntity.ModelParameter;
import org.wlld.tools.ArithUtil;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -23,7 +22,7 @@ import java.util.Map;
*/
public class CoverTest {
public static void main(String[] args) throws Exception {
- cover();
+ cover2();
//test(null, 25, 3);
}
@@ -107,6 +106,14 @@ public class CoverTest {
System.out.println("wrongPoint==" + wrongPoint + "%");
}
+ public static void cover2() throws Exception {
+ Convolution convolution = new Convolution();
+ Picture picture = new Picture();
+ ThreeChannelMatrix threeChannelMatrix = picture.getThreeMatrix("D:\\docment/a.jpg");
+ convolution.kc(threeChannelMatrix, 5, 5);
+
+ }
+
//覆盖率学习 有学习才能有识别
public static void cover() throws Exception {
//创建图片解析类 桔梗覆盖,桔梗焚烧,土壤扰动