java通过opencv运行yolo4

简介: java通过opencv运行yolo4

获取yolo4的模型文件



yolov4.cfg
yolov4.weights
coco.names
复制代码


示例


public static void testYOLO(Mat image) throws IOException {
String config = "E:/opencv4.4.0/age-and-gender-classification/yolo/yolov4.cfg";
String weights = "E:/opencv4.4.0/age-and-gender-classification/yolo/yolov4.weights";
String classesFile = "E:/opencv4.4.0/age-and-gender-classification/yolo/coco.names";
List<String> classes = new ArrayList<String>(); // 存放类别的列表
InputStream in = new FileInputStream(classesFile);
int iAvail = in.available(); // 适用于本地一次读取多个字节时,返回得到的字节数。
byte[] bytes = new byte[iAvail];
in.read(bytes);
String allContent = new String(bytes); // 文件中的所有内容
String[] tempContent = allContent.trim().split("\n"); // allContent去除首尾空格,再按换行符分割。
// 遍历tempContent,添加到保存类别名的列表classes里。
for (int i = 0; i < tempContent.length; i++) {
  classes.add(tempContent[i]);
}
System.out.println(classes.size());
Net net = Dnn.readNetFromDarknet(config, weights);
net.setPreferableBackend(Dnn.DNN_BACKEND_OPENCV);
//  Don't understand command line argument "-cl-no-subgroup-ifp"
//  net.setPreferableTarget(Dnn.DNN_TARGET_OPENCL);
// 改为cpu
net.setPreferableTarget(Dnn.DNN_TARGET_CPU);
Mat im = image.clone();
if (im.empty()) {
  System.out.println("图片加载失败");
}
Size sz = new Size(416, 416);
List<Mat> outs = new ArrayList<>();
Mat blob = Dnn.blobFromImage(image, 0.00392, sz, new Scalar(0), true, false);
net.setInput(blob);
net.forward(outs, getOutputNames(net));
float confThreshold = 0.8f;
List<Rect2d> boxes = new ArrayList<Rect2d>(); // 矩形框列表
List<Integer> classIds = new ArrayList<Integer>(); // 类的序号列表
List<Float> confidences = new ArrayList<Float>(); // 置信度列表
for (int i = 0; i < outs.size(); ++i) {
  Mat level = outs.get(i);
  for (int j = 0; j < level.rows(); ++j) {
    Mat row = level.row(j);
    // [x,y,h,w,c,class1,class2] 所以是标号5
    Mat scores = row.colRange(5, level.cols());
    Core.MinMaxLocResult mm = Core.minMaxLoc(scores);
    float confidence = (float) mm.maxVal;
    Point classIdPoint = mm.maxLoc;
    int size = (int) (level.cols() * level.channels());
    float[] data = new float[size];
    level.get(j, 0, data);
    if (confidence > confThreshold) {
      float x = data[0]; // centerX 矩形中心点的X坐标
      float y = data[1]; // centerY 矩形中心点的Y坐标
      float width = data[2]; // 矩形框的宽
      float height = data[3]; // 矩形框的高
      float xLeftBottom = (x - width / 2) * im.cols(); // 矩形左下角点的X坐标
      float yLeftBottom = (y - height / 2) * im.rows(); // 矩形左下角点的Y坐标
      float xRightTop = (x + width / 2) * im.cols(); // 矩形右上角点的X坐标
      float yRightTop = (y + height / 2) * im.rows(); // 矩形右上角点的Y坐标
      // boxes列表填值 Rect对象,参数是两个点
      boxes.add(new Rect2d(new Point(xLeftBottom, yLeftBottom), new Point(xRightTop, yRightTop)));
      confidences.add(confidence);
      classIds.add((int) classIdPoint.x);
//              Imgproc.rectangle(image, new Point(xLeftBottom, yLeftBottom),
//            new Point(xRightTop, yRightTop), new Scalar(255, 0, 0));
//              Imgproc.putText(image, classes.get((int)classIdPoint.x)+" "+confidence, new Point(xLeftBottom, yLeftBottom),Imgproc.FONT_HERSHEY_PLAIN,0.8, new Scalar(255, 0, 0));
    }
  }
}
System.out.println(classIds);
System.out.println(confidences);
System.out.println(boxes.size());
System.out.println(boxes);
float nmsThresh = 0.5f;
MatOfFloat confidences2 = new MatOfFloat(Converters.vector_float_to_Mat(confidences));
//    Rect2d[] boxesArray = boxes.toArray(new Rect2d[0]);
//    MatOfRect boxes2 = new MatOfRect(boxesArray);
MatOfRect2d m = new MatOfRect2d();
m.fromList(boxes);
MatOfInt indices = new MatOfInt();
/**
 * NMS(Non Maximum Suppression),又名非极大值抑制 删除高度冗余的Rect2d
 */
Dnn.NMSBoxes(m, confidences2, confThreshold, nmsThresh, indices); // We draw the bounding boxes for objects
                                  // here//
int[] ind = indices.toArray();
for (int i = 0; i < ind.length; ++i) {
  int index = ind[i];
  Rect2d box = boxes.get(index);
  int idGuy = classIds.get(index);
  float conf = confidences.get(index);
  Imgproc.rectangle(image, box.tl(), box.br(), new Scalar(255, 0, 0));
  Imgproc.putText(image, classes.get(idGuy) + " " + conf, box.tl(), Imgproc.FONT_HERSHEY_PLAIN, 0.8,
      new Scalar(255, 0, 0));
}
HighGui.imshow("yolo", image);
}
复制代码



效果


网络异常,图片无法展示
|


遇到问题


报错-cl-no-subgroup-ifp 修改为cpu
net.setPreferableTarget(Dnn.DNN_TARGET_CPU);
复制代码


匹配模型过多
NMS(Non Maximum Suppression),又名非极大值抑制 删除高度冗余的Rect2d
复制代码


再NMS需要的是Rect2d
直接从Rect,修改为Rect2d即可


相关文章
|
27天前
|
Java Maven 编译器
Java编译器注解运行和自动生成代码问题之@AutoService工作问题如何解决
Java编译器注解运行和自动生成代码问题之@AutoService工作问题如何解决
|
27天前
|
Java API 编译器
Java编译器注解运行和自动生成代码问题之编译时通过参数设置选项值问题如何解决
Java编译器注解运行和自动生成代码问题之编译时通过参数设置选项值问题如何解决
|
7天前
|
Java PHP 数据安全/隐私保护
Java——IDEA如何运行单个文件
Java——IDEA如何运行单个文件
16 1
Java——IDEA如何运行单个文件
|
28天前
|
Java 程序员 C++
大牛程序员用Java手写JVM:刚好够运行 HelloWorld
大牛程序员用Java手写JVM:刚好够运行 HelloWorld
|
25天前
|
关系型数据库 Java 分布式数据库
PolarDB产品使用问题之部署到服务器上的Java应用(以jar包形式运行)无法连接,如何解决
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
27天前
|
编译器 Java
Java编译器注解运行和自动生成代码问题之重写init方法的问题如何解决
Java编译器注解运行和自动生成代码问题之重写init方法的问题如何解决
|
5天前
|
Oracle Java 关系型数据库
简单记录在Linux上安装JDK环境的步骤,以及解决运行Java程序时出现Error Could not find or load main class XXX问题
本文记录了在Linux系统上安装JDK环境的步骤,并提供了解决运行Java程序时出现的"Error Could not find or load main class XXX"问题的方案,主要是通过重新配置和刷新JDK环境变量来解决。
17 0
|
26天前
|
Java 测试技术 Maven
Java编译器注解运行和自动生成代码问题之在编译时需要设置-proc:none参数问题如何解决
Java编译器注解运行和自动生成代码问题之在编译时需要设置-proc:none参数问题如何解决
|
27天前
|
Java Maven 编译器
Java编译器注解运行和自动生成代码问题之RoundEnvironment和注解类型集合有什么区别
Java编译器注解运行和自动生成代码问题之RoundEnvironment和注解类型集合有什么区别
|
27天前
|
Java 编译器
Java编译器注解运行和自动生成代码问题之指定一个注解处理器处理所有类型的注解的问题如何解决
Java编译器注解运行和自动生成代码问题之指定一个注解处理器处理所有类型的注解的问题如何解决