mirror of
https://gitee.com/dromara/easyAi.git
synced 2024-12-02 11:48:08 +08:00
创建图像识别超市
This commit is contained in:
parent
9c6b2eb171
commit
ae8bdcce71
@ -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<Integer, Double> rightTagging = new HashMap<>();//分类标注
|
||||
Map<Integer, Double> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
31
src/main/java/org/wlld/config/Kernel.java
Normal file
31
src/main/java/org/wlld/config/Kernel.java
Normal file
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
61
src/main/java/org/wlld/imageRecognition/Convolution.java
Normal file
61
src/main/java/org/wlld/imageRecognition/Convolution.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
68
src/main/java/org/wlld/imageRecognition/Operation.java
Normal file
68
src/main/java/org/wlld/imageRecognition/Operation.java
Normal file
@ -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<Double> 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<Integer, Double> tagging) throws Exception {
|
||||
List<Double> list = convolution(matrix);
|
||||
intoNerve(1, list, templeConfig.getSensoryNerves(), true, tagging);
|
||||
}
|
||||
|
||||
//图像视觉
|
||||
public void look(Matrix matrix, long eventId) throws Exception {
|
||||
List<Double> list = convolution(matrix);
|
||||
intoNerve(eventId, list, templeConfig.getSensoryNerves(), false, null);
|
||||
}
|
||||
|
||||
private List<Double> sub(Matrix matrix) throws Exception {//
|
||||
List<Double> 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<Double> featurList, List<SensoryNerve> sensoryNerveList
|
||||
, boolean isStudy, Map<Integer, Double> map) throws Exception {
|
||||
for (int i = 0; i < sensoryNerveList.size(); i++) {
|
||||
sensoryNerveList.get(i).postMessage(eventId, featurList.get(i), isStudy, map);
|
||||
}
|
||||
}
|
||||
}
|
76
src/main/java/org/wlld/imageRecognition/Picture.java
Normal file
76
src/main/java/org/wlld/imageRecognition/Picture.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
84
src/main/java/org/wlld/imageRecognition/TempleConfig.java
Normal file
84
src/main/java/org/wlld/imageRecognition/TempleConfig.java
Normal file
@ -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<SensoryNerve> 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;
|
||||
}
|
||||
}
|
@ -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<Ma> 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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user