使用Dnn调用神经网络实例,查找了2个多月的方法,在无数的百度和谷歌和git中学习到了使用opencv+java内置的神经网络处理函数来解决模型调用问题
主要是maven配置的自带jar包版本太老了,说白了其实maven其实就是更方便地让自己得到自己所需要的jar包,打包的时候非常让人痛苦,还不如简单地建立一个java工程文件。不过可以去百度搜索maven官网,去下载自己所需要的jar包,然后放在自己的项目中,这样比较方便。
使用javacv1.5.1-platrom,低版本没有此例方法(或者说maven版本的jar包功能不齐全)。
package BodyDetection;
import org.bytedeco.javacpp.indexer.FloatIndexer;
import org.bytedeco.opencv.opencv_core.*;
import org.bytedeco.opencv.opencv_dnn.*;
import static org.bytedeco.opencv.global.opencv_core.*;
import static org.bytedeco.opencv.global.opencv_dnn.*;
import static org.bytedeco.opencv.global.opencv_imgproc.*;
public class bodyDetection {
//模型文件路径
private static final String pbload = System.getProperty("user.dir")+"\\resources\\frozen_inference_graph.pb";
private static final String pbtxtload = System.getProperty("user.dir")+"\\resources\\graph.pbtxt";
private static Net net = null;
static {
net = readNetFromTensorflow(pbload, pbtxtload);
}
public static void detectAndDraw(Mat image) {
int ws=image.rows();
int hs=image.cols();
System.out.println(ws);
System.out.println(hs);
resize(image, image, new Size(300, 300));//调整图像大小以匹配模型的输入大小
Mat blob = blobFromImage(image, 1.0, new Size(300, 300), new Scalar(104.0, 177.0, 123.0, 0), false, false, CV_32F);
net.setInput(blob);//将输入设置为网络模型
Mat output = net.forward();//将输入转发给Dnn神经网络,得到输出矩阵
Mat ne = new Mat(new Size(output.size(3), output.size(2)), CV_32F, output.ptr(0, 0));//提取一个2d矩阵用于4d输出矩阵,形式为(检测次数x 7)
//这里可以这样理解,这个索引器识别了图中的关键点(人),以点为中心,向四周画框,然后把重绘的图(画好框的图),覆盖在原来的图上,不要理解错误了
FloatIndexer srcIndexer = ne.createIndexer(); // 创建索引器来访问矩阵的元素
//System.out.println(srcIndexer);
int testnub=0;
for (int i = 0; i < output.size(3); i++) {//迭代提取元素
float confidence = srcIndexer.get(i, 2);
float f1 = srcIndexer.get(i, 3);
float f2 = srcIndexer.get(i, 4);
float f3 = srcIndexer.get(i, 5);
float f4 = srcIndexer.get(i, 6);
if (confidence > .6) {
float tx = f1 * 300;//top left point's x
float ty = f2 * 300;//top left point's y
float bx = f3 * 300;//bottom right point's x
float by = f4 * 300;//bottom right point's y
rectangle(image, new Rect(new Point((int) tx, (int) ty), new Point((int) bx, (int) by)), new Scalar(255, 0, 0, 0));//print blue rectangle
testnub++;
}
}
resize(image, image, new Size(640, 480));//还原
//System.out.println(testnub);
}
}