|
|
|
@ -14,15 +14,18 @@
|
|
|
|
|
* 比如你要分辨当前图像 是 苹果或是香蕉或是桃子,对图像进行判断分类,精准度更高,对图像的切割,针对占比比较大的物体切割,定位。
|
|
|
|
|
* 下面API文档有不清楚的地方可联系作者询问,QQ:794757862
|
|
|
|
|
## 好的让我们从HELLO WORLD 开始:
|
|
|
|
|
public class HelloWorld {
|
|
|
|
|
public static void testPic() throws Exception {
|
|
|
|
|
//测试SPEED模式学习过程
|
|
|
|
|
//初始化图像转矩阵类:作用就是说将一个图片文件转化为矩阵类
|
|
|
|
|
Picture picture = new Picture();
|
|
|
|
|
//初始化配置模板类,设置模式为SPEED_PATTERN模式 即速度模式
|
|
|
|
|
TempleConfig templeConfig = getTemple(true, StudyPattern.Speed_Pattern);
|
|
|
|
|
//初始化计算类,并将配置模版载入计算类
|
|
|
|
|
Operation operation = new Operation(templeConfig);
|
|
|
|
|
//初始化计算类,并将配置模版和输出回调类载入计算类
|
|
|
|
|
//运算类有两个构造一个是配置回调类,一个是不配置回调类
|
|
|
|
|
//若使用定位功能,则无需配置回调类,若不启用,则要配置回调类
|
|
|
|
|
//回调类要实现OutBack接口中的方法
|
|
|
|
|
Ma ma = new Ma();
|
|
|
|
|
Operation operation = new Operation(templeConfig, ma);
|
|
|
|
|
//标注主键为 第几种分类,值为标注 1 是TRUE 0是FALSE
|
|
|
|
|
//给训练图像进行标注,健是分类的ID,对应的就是输出结果的ID值,值要么写0要么写1
|
|
|
|
|
// 1就是 是这种分类,0就是不是这种分类
|
|
|
|
@ -34,8 +37,7 @@
|
|
|
|
|
for (int i = 1; i < 999; i++) {
|
|
|
|
|
System.out.println("开始学习1==" + i);
|
|
|
|
|
//读取本地URL地址图片(适用于电脑本地图片),并转化成矩阵
|
|
|
|
|
//注意学习图片至少要一千张+同物体的不同图片,推荐一万张
|
|
|
|
|
//学习的越多就越准,拿同样的图片反复循环学习是没用的
|
|
|
|
|
//注意学习图片至少要一千张+同物体的不同图片,学习的越多就越准,拿同样的图片反复循环学习是没用的
|
|
|
|
|
//picture.getImageMatrixByIo(InputStream) 另外一个api,是通过字节流读取图片矩阵,适用于网络传输的图片
|
|
|
|
|
Matrix right = picture.getImageMatrixByLocal("/Users/lidapeng/Desktop/myDocment/c/c" + i + ".png");
|
|
|
|
|
Matrix wrong = picture.getImageMatrixByLocal("/Users/lidapeng/Desktop/myDocment/b/b" + i + ".png");
|
|
|
|
@ -45,6 +47,9 @@
|
|
|
|
|
//wrong这个矩阵是错误的图片,所以要配置上面错误的标注0.0 学习 告诉计算机这个图片是错误的
|
|
|
|
|
operation.study(wrong, wrongTagging);
|
|
|
|
|
}
|
|
|
|
|
//如果启用物体坐标定位,则在学习结束的时候,一定要执行boxStudy方法
|
|
|
|
|
//若不启用,则请不要使用,否则会报错
|
|
|
|
|
//templeConfig.boxStudy();
|
|
|
|
|
//获取训练结束的模型参数,提取出来转化成JSON保存数据库,下次服务启动时不用学习
|
|
|
|
|
//直接将模型参数注入
|
|
|
|
|
//获取模型MODLE 这个模型就是我们程序学习的目的,学习结束后我们要拿到这个模型
|
|
|
|
@ -52,6 +57,7 @@
|
|
|
|
|
//将模型MODEL转化成JSON 字符串 保存到数据库 留待下次服务启动的时候,识别提取用
|
|
|
|
|
String model = JSON.toJSONString(modelParameter);
|
|
|
|
|
//以上就是SPEED模式下的学习全过程,识别的过程就是再次初始化,将学习结果注入之后使用
|
|
|
|
|
|
|
|
|
|
//识别过程
|
|
|
|
|
//将从数据库取出的JSON字符串转化为模型MODEL
|
|
|
|
|
ModelParameter modelParameter1 = JSONObject.parseObject(model, ModelParameter.class);
|
|
|
|
@ -61,22 +67,21 @@
|
|
|
|
|
templeConfig1.insertModel(modelParameter1);
|
|
|
|
|
//将配置模板配置到运算类
|
|
|
|
|
Operation operation1 = new Operation(templeConfig1);
|
|
|
|
|
//获取本地图片字节码转化成降纬后的灰度矩阵</br>
|
|
|
|
|
//获取本地图片字节码转化成降纬后的灰度矩阵
|
|
|
|
|
Matrix right = picture.getImageMatrixByLocal("/Users/lidapeng/Desktop/myDocment/test/a101.png");
|
|
|
|
|
Matrix wrong = picture.getImageMatrixByLocal("/Users/lidapeng/Desktop/myDocment/b/b1000.png");
|
|
|
|
|
//进行图像识别 参数说明 eventId,事件id,因为输出结果是在回调类回调的,所以必须有个主键去判断事件
|
|
|
|
|
//说明你回调是响应的哪一次调用的ID,所以每一次识别调用,请用不同的id
|
|
|
|
|
operation1.look(wrong, 3);
|
|
|
|
|
operation1.look(right, 2);
|
|
|
|
|
//若启用定位功能检测请使用lookWithPosition,若没有启用,使用检测会报错
|
|
|
|
|
//返回map,主键是分类id,值是该图片中此分类有多少个物体,每个物体的具体位置坐标的大小
|
|
|
|
|
//Map<Integer, List<FrameBody>> map = operation1.lookWithPosition(right, 4);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static TempleConfig getTemple(boolean isFirst, int pattern) throws Exception {
|
|
|
|
|
//创建一个配置模板类,作用:主要是保存及载入一些配置参数用
|
|
|
|
|
TempleConfig templeConfig = new TempleConfig();
|
|
|
|
|
//创建一个回调类,图像识别最后输出结果,在这个类输出,这个类要实现 OutBack接口
|
|
|
|
|
Ma ma = new Ma();//创建一个回调类
|
|
|
|
|
//将这个回调类注册到配置模版里 必写
|
|
|
|
|
templeConfig.setOutBack(ma);
|
|
|
|
|
//全连接层深度,选填可不填 不填默认值为2
|
|
|
|
|
//这就像人类大脑的意识深度原理一样,深度学习越深,训练结果越准,但是训练量成几何倍数增加
|
|
|
|
|
//比如默认深度是2 需要 正负模板各一千+张照片进行训练。识别率70%(数值只是举个例子,不是具体数值)
|
|
|
|
@ -85,8 +90,14 @@
|
|
|
|
|
//但是有极限,即超过某个深度,即使再增加深度,识别率反而会下降。需要具体不断尝试找到 合适的深度
|
|
|
|
|
//注意:若深度提升,训练量没有成倍增长,则准确度反而更低!
|
|
|
|
|
templeConfig.setDeep(2);
|
|
|
|
|
//启用定位学习 注意启用在图片中对某个物体进行定位,要注意
|
|
|
|
|
//学习的图片必须除了学习的物体以外,其他位置都是白色或者空白(即用PS扣空)。
|
|
|
|
|
//即该图片除了这个物体,没有其他任何干扰杂色(一个像素的杂色都不可以有)
|
|
|
|
|
//templeConfig.setHavePosition(true);
|
|
|
|
|
//窗口类,就是用来扫描图片的窗口大小和移动距离的设定
|
|
|
|
|
//Frame frame = new Frame();
|
|
|
|
|
//初始化配置模版,参数说明(int studyPattern, boolean initPower, int width, int height
|
|
|
|
|
, int classificationNub)
|
|
|
|
|
//, int classificationNub)
|
|
|
|
|
//studyPattern 学习模式:常量值 StudyPattern.Accuracy_Pattern;StudyPattern.Speed_Pattern
|
|
|
|
|
//第一种模式精准模式,第二种模式是速度模式
|
|
|
|
|
//精准模式顾名思义,准确相对高很多,但是缺点也很明显学习速度慢,不是一般的慢,CPU学习1000张图片
|
|
|
|
@ -105,6 +116,7 @@
|
|
|
|
|
//要识别和学习的图片尺寸与这个宽高比 必要相差太大就好,而且宁长勿短
|
|
|
|
|
//classificationNub 要识别的有几个分类,比如我就识别苹果,就是1 有两种苹果橘子就是 2
|
|
|
|
|
templeConfig.init(pattern, isFirst, 3204, 4032, 1);
|
|
|
|
|
|
|
|
|
|
return templeConfig;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -120,6 +132,7 @@
|
|
|
|
|
ModelParameter modelParameter2 = templeConfig2.getModel();
|
|
|
|
|
String model2 = JSON.toJSONString(modelParameter2);
|
|
|
|
|
System.out.println(model2);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void testPic2() throws Exception {
|
|
|
|
@ -132,7 +145,7 @@
|
|
|
|
|
Map<Integer, Double> wrongTagging = new HashMap<>();//分类标注
|
|
|
|
|
rightTagging.put(1, 1.0);
|
|
|
|
|
wrongTagging.put(1, 0.0);
|
|
|
|
|
for (int i = 1; i < 5; i++) {
|
|
|
|
|
for (int i = 1; i < 2; i++) {
|
|
|
|
|
System.out.println("开始学习1==" + i);
|
|
|
|
|
//读取本地URL地址图片,并转化成矩阵
|
|
|
|
|
Matrix right = picture.getImageMatrixByLocal("/Users/lidapeng/Desktop/myDocment/c/c" + i + ".png");
|
|
|
|
@ -140,10 +153,11 @@
|
|
|
|
|
//将图像矩阵和标注加入进行学习 注意的是 Accuracy_Pattern 模式 要学习两次
|
|
|
|
|
//这里使用learning方法,前两个参数与SPEED模式相同,多了一个第三个参数
|
|
|
|
|
//第一次学习的时候 这个参数必须是 false
|
|
|
|
|
//最后一个参数id
|
|
|
|
|
operation.learning(right, rightTagging, false);
|
|
|
|
|
operation.learning(wrong, wrongTagging, false);
|
|
|
|
|
}
|
|
|
|
|
for (int i = 1; i < 5; i++) {//神经网络学习
|
|
|
|
|
for (int i = 1; i < 2; i++) {//神经网络学习
|
|
|
|
|
System.out.println("开始学习2==" + i);
|
|
|
|
|
//读取本地URL地址图片,并转化成矩阵
|
|
|
|
|
Matrix right = picture.getImageMatrixByLocal("/Users/lidapeng/Desktop/myDocment/c/c" + i + ".png");
|
|
|
|
@ -159,7 +173,7 @@
|
|
|
|
|
//若有疑问可以参考一下 testModel()方法
|
|
|
|
|
operation.look(right, 2);
|
|
|
|
|
operation.look(wrong, 3);
|
|
|
|
|
}}
|
|
|
|
|
}
|
|
|
|
|
回调输出类:
|
|
|
|
|
public class Ma implements OutBack {
|
|
|
|
|
private int nub;
|
|
|
|
@ -177,3 +191,8 @@
|
|
|
|
|
回调第一个参数是输出值 指的是 这个分类的概率 该数值是0-1之间的浮点
|
|
|
|
|
第二个参数是 分类的id 判断是训练的哪个分类的ID,
|
|
|
|
|
第三个参数是 事件ID,一次判断事件 使用一个ID,让开发者知道是哪次事件的回调判断
|
|
|
|
|
|
|
|
|
|
#### 最终说明
|
|
|
|
|
* TempleConfig():配置模版类一定要静态,在内存中长期持有
|
|
|
|
|
* Operation():运算类,除了学习可以使用一个以外,用户每检测一次都要NEW一次。
|
|
|
|
|
因为学习是单线程无所谓,而检测是多线程,如果使用一个运算类,可能会造成线程安全问题
|