diff --git a/src/main/java/org/wlld/App.java b/src/main/java/org/wlld/App.java index c8cbef4..64c2854 100644 --- a/src/main/java/org/wlld/App.java +++ b/src/main/java/org/wlld/App.java @@ -1,24 +1,63 @@ package org.wlld; -import org.wlld.nerveCenter.NerveManager; +import org.wlld.MatrixTools.Matrix; +import org.wlld.imageRecognition.Operation; +import org.wlld.imageRecognition.Picture; +import org.wlld.imageRecognition.TempleConfig; +import org.wlld.test.Ma; + +import java.util.HashMap; +import java.util.Map; /** * 测试入口类! */ public class App { public static void main(String[] args) throws Exception { - createNerveTest(); + //createNerveTest(); + testPic(); } - public static void createNerveTest() throws Exception { - //构建一个全连接神经网络管理器,参数:(感知神经元个数,隐层神经元个数,输出神经元个数,输出神经元深度) - //一个神经网络管理管理一个神经网络学习内容, - NerveManager nerveManager = - new NerveManager(2, 2, 1, 1); - //开始构建神经网络,参数为是否初始化权重及阈值,若 - nerveManager.setStudyPoint(0.1);//设置学习率(取值范围是0-1开区间),若不设置默认为0.1 - nerveManager.init(true); - - + public static void testPic() throws Exception { + //初始化图像转矩阵类 + Picture picture = new Picture(); + //初始化配置模板类 + TempleConfig templeConfig = new TempleConfig(); + //创建一个回调类 + Ma ma = new Ma();//创建一个回调类 + //注册输出结果回调类 必写 + templeConfig.setOutBack(ma); + //全连接层深度,默认为2 选填 + templeConfig.setDeep(2); + //要学习几种分类 默认为1 选填 + templeConfig.setClassificationNub(1); + //设置图像行列比例的行,默认为5 选填 + templeConfig.setRow(5); + //设置图像行列比例的列,默认为3 选填 + templeConfig.setColumn(3); + //对模版进行初始化 Ps:初始化一定要在所有参数设置完成后设置,否则设置无效。 + // 使用默认值(模型参数注入除外) + templeConfig.initNerveManager(true);//对模板初始化 + //初始化计算类 + Operation operation = new Operation(templeConfig); + //初始化模板标注 + Map rightTagging = new HashMap<>();//分类标注 + Map wrongTagging = new HashMap<>();//分类标注 + rightTagging.put(1, 1.0); + wrongTagging.put(1, 0.0); + for (int i = 1; i < 999; i++) { + System.out.println("开始学习1==" + i); + Matrix right = picture.getImageMatrixByLocal("/Users/lidapeng/Desktop/myDocment/c/c" + i + ".png"); + Matrix wrong = picture.getImageMatrixByLocal("/Users/lidapeng/Desktop/myDocment/b/b" + i + ".png"); + operation.study(right, rightTagging); + operation.study(wrong, wrongTagging); + } + Matrix right = picture.getImageMatrixByLocal("/Users/lidapeng/Desktop/myDocment/c/c1000.png"); + Matrix wrong = picture.getImageMatrixByLocal("/Users/lidapeng/Desktop/myDocment/b/b1000.png"); + ma.setNub(1); + operation.look(right, 2); + ma.setNub(2); + operation.look(wrong, 3); } + } diff --git a/src/main/java/org/wlld/config/GraphConfig.java b/src/main/java/org/wlld/config/GraphConfig.java deleted file mode 100644 index 171217e..0000000 --- a/src/main/java/org/wlld/config/GraphConfig.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.wlld.config; - -/** - * @author lidapeng - * @description 图检索配置常量表 - * @date 9:41 上午 2020/1/7 - */ -public class GraphConfig { - // - public static final double Cut_Threshold = 10; -} diff --git a/src/main/java/org/wlld/config/Kernel.java b/src/main/java/org/wlld/config/Kernel.java new file mode 100644 index 0000000..5fe4363 --- /dev/null +++ b/src/main/java/org/wlld/config/Kernel.java @@ -0,0 +1,31 @@ +package org.wlld.config; + +import org.wlld.MatrixTools.Matrix; +import org.wlld.tools.ArithUtil; + +public class Kernel { + private static final String Vertical_Number = "[-1,0,1]#[-2,0,2]#[-1,0,1]#";//竖卷积核 + private static final String Horizontal_Number = "[-1,-2,-1]#[0,0,0]#[1,2,1]#";//横卷积核 + private static final String All_Number = "[1,-2,1]#[-2,4,-2]#[1,-2,1]#";//角卷积 + private static final String All_Number2 = "[-1,0,-1]#[0,4,0]#[-1,0,-1]#"; + public static Matrix Vertical; + public static Matrix Horizontal; + public static Matrix All; + public static Matrix ALL_Two; + public static final int Unit = 100; + public static final double Pi = ArithUtil.div(ArithUtil.div(Math.PI, 2), Unit); + + private Kernel() { + } + + static { + try { + ALL_Two = new Matrix(3, 3, All_Number2); + All = new Matrix(3, 3, All_Number); + Vertical = new Matrix(3, 3, Vertical_Number); + Horizontal = new Matrix(3, 3, Horizontal_Number); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/org/wlld/imageRecognition/Convolution.java b/src/main/java/org/wlld/imageRecognition/Convolution.java new file mode 100644 index 0000000..094c133 --- /dev/null +++ b/src/main/java/org/wlld/imageRecognition/Convolution.java @@ -0,0 +1,61 @@ +package org.wlld.imageRecognition; + +import org.wlld.MatrixTools.Matrix; +import org.wlld.MatrixTools.MatrixOperation; +import org.wlld.config.Kernel; + +/** + * @author lidapeng + * 图像卷积 + * @date 9:23 上午 2020/1/2 + */ +public class Convolution { + public Matrix getFeatures(Matrix matrix, int maxNub) throws Exception { + do { + matrix = convolution(matrix, Kernel.ALL_Two); + } + while (matrix.getX() > maxNub && matrix.getY() > maxNub); + //已经不可以再缩小了,最后做一层卷积,然后提取最大值 + return matrix; + } + + private Matrix convolution(Matrix matrix, Matrix kernel) throws Exception { + int x = matrix.getX() - 2;//求导后矩阵的行数 + int y = matrix.getY() - 2;//求导后矩阵的列数 + Matrix myMatrix = new Matrix(x, y);//最终合成矩阵 + for (int i = 0; i < x; i++) {//遍历行 + for (int j = 0; j < y; j++) {//遍历每行的列 + double dm = MatrixOperation.convolution(matrix, kernel, i, j); + if (dm > 0) {//存在边缘 + myMatrix.setNub(i, j, dm); + } + } + } + return late(myMatrix); + } + + public Matrix late(Matrix matrix) throws Exception {//迟化处理 + int xn = matrix.getX(); + int yn = matrix.getY(); + int x = xn / 2;//求导后矩阵的行数 + int y = yn / 2;//求导后矩阵的列数 + Matrix myMatrix = new Matrix(x, y);//迟化后的矩阵 + for (int i = 0; i < xn - 2; i += 2) { + for (int j = 0; j < yn - 2; j += 2) { + Matrix matrix1 = matrix.getSonOfMatrix(i, j, 2, 2); + double maxNub = 0; + for (int t = 0; t < matrix1.getX(); t++) { + for (int k = 0; k < matrix1.getY(); k++) { + double nub = matrix1.getNumber(t, k); + if (nub > maxNub) { + maxNub = nub; + } + } + } + //迟化的最大值是 MAXNUB + myMatrix.setNub(i / 2, j / 2, maxNub); + } + } + return myMatrix; + } +} diff --git a/src/main/java/org/wlld/imageRecognition/Operation.java b/src/main/java/org/wlld/imageRecognition/Operation.java new file mode 100644 index 0000000..fa097be --- /dev/null +++ b/src/main/java/org/wlld/imageRecognition/Operation.java @@ -0,0 +1,68 @@ +package org.wlld.imageRecognition; + + +import org.wlld.MatrixTools.Matrix; +import org.wlld.nerveEntity.SensoryNerve; +import org.wlld.tools.ArithUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class Operation {//进行计算 + private TempleConfig templeConfig;//配置初始化参数模板 + private Convolution convolution = new Convolution(); + + public Operation(TempleConfig templeConfig) { + this.templeConfig = templeConfig; + } + + public List convolution(Matrix matrix) throws Exception { + //进行卷积 + int maxNub = 0; + if (templeConfig.getRow() >= templeConfig.getColumn()) { + maxNub = templeConfig.getRow(); + } else { + maxNub = templeConfig.getColumn(); + } + Matrix matrix1 = convolution.getFeatures(matrix, maxNub); + return sub(matrix1); + } + + //模板学习 + public void study(Matrix matrix, Map tagging) throws Exception { + List list = convolution(matrix); + intoNerve(1, list, templeConfig.getSensoryNerves(), true, tagging); + } + + //图像视觉 + public void look(Matrix matrix, long eventId) throws Exception { + List list = convolution(matrix); + intoNerve(eventId, list, templeConfig.getSensoryNerves(), false, null); + } + + private List sub(Matrix matrix) throws Exception {// + List list = new ArrayList<>(); + int x = matrix.getX() - 1; + int y = matrix.getY() - 1; + for (int i = 0; i < templeConfig.getRow(); i++) { + for (int j = 0; j < templeConfig.getColumn(); j++) { + if (i > x || j > y) { + list.add(0.0); + } else { + //归一化处理 + double nub = ArithUtil.div(matrix.getNumber(i, j), 10000000); + list.add(nub); + } + } + } + return list; + } + + private void intoNerve(long eventId, List featurList, List sensoryNerveList + , boolean isStudy, Map map) throws Exception { + for (int i = 0; i < sensoryNerveList.size(); i++) { + sensoryNerveList.get(i).postMessage(eventId, featurList.get(i), isStudy, map); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/wlld/imageRecognition/Picture.java b/src/main/java/org/wlld/imageRecognition/Picture.java new file mode 100644 index 0000000..9fef0b4 --- /dev/null +++ b/src/main/java/org/wlld/imageRecognition/Picture.java @@ -0,0 +1,76 @@ +package org.wlld.imageRecognition; + +import org.wlld.MatrixTools.Matrix; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.InputStream; + +public class Picture { + private int pictureWidth; + private int pictureHeight; + + //从本地文件拿出图像矩阵 + public Matrix getImageMatrixByLocal(String fileURL) throws Exception { + File file = new File(fileURL); + BufferedImage bi = null; + try { + bi = ImageIO.read(file); + } catch (Exception e) { + e.printStackTrace(); + } + return getImage(bi); + } + + // + public Matrix getImageMatrixByIo(InputStream inputStream) throws Exception { + BufferedImage bi = null; + try { + bi = ImageIO.read(inputStream); + } catch (Exception e) { + e.printStackTrace(); + } + return getImage(bi); + } + + private Matrix getImage(BufferedImage bi) throws Exception { + int width = bi.getWidth();//最大宽度 + int height = bi.getHeight();//最大高度 + pictureWidth = width; + pictureHeight = height; + Matrix matrix = new Matrix(height, width);//行,列 + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + int pixel = bi.getRGB(j, i);// 下面三行代码将一个数字转换为RGB数字 + double grab = dimensionReduction(pixel);//抽取灰度 + matrix.setNub(i, j, grab); + } + } + return matrix; + } + + public double dimensionReduction(int pixel) {//提取灰度进行降维 + int r = (pixel & 0xff0000) >> 16;//R + int g = (pixel & 0xff00) >> 8;//G + int b = (pixel & 0xff);//B + double gray = (r * 38 + g * 75 + b * 15) >> 7; + return gray; + } + + public int getPictureWidth() { + return pictureWidth; + } + + public void setPictureWidth(int pictureWidth) { + this.pictureWidth = pictureWidth; + } + + public int getPictureHeight() { + return pictureHeight; + } + + public void setPictureHeight(int pictureHeight) { + this.pictureHeight = pictureHeight; + } +} diff --git a/src/main/java/org/wlld/imageRecognition/TempleConfig.java b/src/main/java/org/wlld/imageRecognition/TempleConfig.java new file mode 100644 index 0000000..97a0143 --- /dev/null +++ b/src/main/java/org/wlld/imageRecognition/TempleConfig.java @@ -0,0 +1,84 @@ +package org.wlld.imageRecognition; + +import org.wlld.i.OutBack; +import org.wlld.nerveCenter.NerveManager; +import org.wlld.nerveEntity.SensoryNerve; + +import java.util.List; + + +public class TempleConfig { + private NerveManager nerveManager; + public double cutThreshold = 10;//切割阈值默认值 + public int row = 5;//行的最小比例 + public int column = 3;//列的最小比例 + public int deep = 2;//默认深度 + public int classificationNub = 1;//分类的数量 + private OutBack outBack; + + public void initNerveManager(boolean initPower) throws Exception {//初始化神经网络 + if (row >= 5 || column >= 5) { + nerveManager = new NerveManager(row * column, 6, classificationNub, deep); + nerveManager.init(initPower); + nerveManager.setOutBack(outBack); + } else { + throw new Exception("row or column is too min"); + } + } + + public List getSensoryNerves() {//获取感知神经元 + return nerveManager.getSensoryNerves(); + } + + public void setStudy(double studyPoint) throws Exception {//设置学习率 + nerveManager.setStudyPoint(studyPoint); + } + + public double getCutThreshold() { + return cutThreshold; + } + + public void setCutThreshold(double cutThreshold) { + this.cutThreshold = cutThreshold; + } + + public int getRow() { + return row; + } + + public void setRow(int row) { + this.row = row; + } + + public int getColumn() { + return column; + } + + public void setColumn(int column) { + this.column = column; + } + + public int getDeep() { + return deep; + } + + public void setDeep(int deep) { + this.deep = deep; + } + + public int getClassificationNub() { + return classificationNub; + } + + public void setClassificationNub(int classificationNub) { + this.classificationNub = classificationNub; + } + + public OutBack getOutBack() { + return outBack; + } + + public void setOutBack(OutBack outBack) { + this.outBack = outBack; + } +} diff --git a/src/main/java/org/wlld/test/Ma.java b/src/main/java/org/wlld/test/Ma.java index 919acc3..d20b720 100644 --- a/src/main/java/org/wlld/test/Ma.java +++ b/src/main/java/org/wlld/test/Ma.java @@ -1,20 +1,21 @@ package org.wlld.test; -import java.util.ArrayList; -import java.util.List; +import org.wlld.i.OutBack; /** * @author lidapeng * @description * @date 2:12 下午 2020/1/7 */ -public class Ma { - private int x; - private int y; - private List mas = new ArrayList<>(); +public class Ma implements OutBack { + private int nub; - Ma(int x, int y) { - this.x = x; - this.y = y; + public void setNub(int nub) { + this.nub = nub; + } + + @Override + public void getBack(double out, int id, long eventId) { + System.out.println("id==" + id + ",out==" + out + ",nub==" + nub); } } diff --git a/src/main/java/org/wlld/test/Test.java b/src/main/java/org/wlld/test/Test.java index d33e4e6..3974faf 100644 --- a/src/main/java/org/wlld/test/Test.java +++ b/src/main/java/org/wlld/test/Test.java @@ -7,11 +7,6 @@ package org.wlld.test; */ public class Test { public static void main(String[] args) { - long a = System.currentTimeMillis(); - for (int i = 0; i < 12100000; i++) { - Ma ma = new Ma(1, 1); - } - long b = System.currentTimeMillis(); - System.out.println(b - a); + } }