opencv移动检测,物体识别(java篇)

  首先下载安装包

URL
安装后复制路劲opencv\build\java Java jar包,添加到自己的项目
以maven项目为例

<dependency>
            <groupId>org.openpnp</groupId>
            <artifactId>opencv</artifactId>
            <version>4.5.1-2</version>
        </dependency>

安装包的‪opencv_java451.dll 移动到‪C:\Windows\System32\opencv_java451.dll
好了开始粘贴代码


移动侦测
 

File tempFile = new File("E:\\temp\\", "uploadedVideo" + ".mp4");
        videoFile.transferTo(tempFile);
        System.out.println(tempFile.getAbsolutePath());
        // 初始化视频读取
        VideoCapture cap = new VideoCapture(tempFile.getAbsolutePath());
        if (!cap.isOpened()) {
            System.out.println("Error: Cannot open video file.");
            return false;
        }
        Mat frame1 = new Mat();
        Mat frame2 = new Mat();
        Mat gray1 = new Mat();
        Mat gray2 = new Mat();

        // 读取第一帧
        cap.read(frame1);
        Imgproc.cvtColor(frame1, gray1, Imgproc.COLOR_BGR2GRAY);

        // 定义矩形结构元素
        Mat rectangleKernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5, 5));

        int frameCount = 1;
        double imageArea = frame1.cols() * frame1.rows(); // 计算图像总面积(像素)
        double minAreaThresholdRatio = 0.01; // 设置最小面积阈值比例(例如1%)
        double minAreaThreshold = imageArea * minAreaThresholdRatio; // 计算最小面积阈值
        while (true) {
            // 读取下一帧
            boolean ret = cap.read(frame2);
            if (!ret) {
                break;  // 如果视频结束,跳出循环
            }

            Imgproc.cvtColor(frame2, gray2, Imgproc.COLOR_BGR2GRAY);

            // 计算两帧的差异
            Mat diff = new Mat();
            Core.absdiff(gray1, gray2, diff);

            // 二值化以突出差异
            Mat thresh = new Mat();
            Imgproc.threshold(diff, thresh, 30, 255, Imgproc.THRESH_BINARY);
            Imgproc.dilate(thresh, thresh, rectangleKernel, new Point(-1, -1), 2);  // 膨胀操作,使轮廓更清晰

            // 找出轮廓
            List<MatOfPoint> contours = new ArrayList<>();
            Mat hierarchy = new Mat();
            Imgproc.findContours(thresh, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

            // 如果检测到任何轮廓,表示有移动物体,返回true
            if (!contours.isEmpty()) {
                MatOfPoint largestContour = contours.stream().max((c1, c2) -> Double.compare(Imgproc.contourArea(c1), Imgproc.contourArea(c2))).get();
                double area = Imgproc.contourArea(largestContour);
                if (area > minAreaThreshold) {
                    Rect boundingRect = Imgproc.boundingRect(largestContour);
                    Imgproc.rectangle(frame2, boundingRect, new Scalar(0, 255, 0), 2);  // 用绿色矩形框出
                    Imgcodecs.imwrite("E:\\temp\\diff\\Thresh" + frameCount + ".jpg", thresh);
                    Imgcodecs.imwrite("E:\\temp\\Diff\\Frame" + frameCount + ".jpg", frame2);
                    // 释放资源
                    cap.release();
                    HighGui.destroyAllWindows();
                    return true;
                }
            }
            frameCount++;
            // 准备下一次迭代
            gray1 = gray2.clone();
        }
        // 释放资源
        cap.release();
        HighGui.destroyAllWindows();
        return false;

物体识别(使用配置YOLO模型)

 public void MotionDetectionByAnimalImg(MultipartFile videoFile) throws IOException {
        // Load the native OpenCV library
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        File tempFile = new File("E:\\temp\\", "uploadedVideo" + "jpg");
        videoFile.transferTo(tempFile);  // Assuming this is done somewhere before
        // 读取coco.names文件
        String classesFile = "E:\\config\\coco.names";
        // 配置YOLO模型
        String modelConfiguration = "E:\\config\\yolov3.cfg";
        String modelWeights = "E:\\config\\yolov3.weights";

        // 输出图片路径
        String outputImageFile = "E:\\temp\\cache\\output_image.jpg";

        List<String> classNames = Files.readAllLines(Paths.get(classesFile));

        Net net = Dnn.readNetFromDarknet(modelConfiguration, modelWeights);
        net.setPreferableBackend(Dnn.DNN_BACKEND_OPENCV);
        net.setPreferableTarget(Dnn.DNN_TARGET_CPU);

        // 读取图片
        Mat image = Imgcodecs.imread(tempFile.getAbsolutePath());
        if (image.empty()) {
            System.out.println("Error: Could not open image.");
            return;
        }

        Mat blob = Dnn.blobFromImage(image, 1 / 255.0, new Size(416, 416), new Scalar(0, 0, 0), true, false);
        net.setInput(blob);

        List<Mat> result = new ArrayList<>();
        List<String> outBlobNames = getOutputNames(net);
        net.forward(result, outBlobNames);

        findObjects(result, image, classNames);

        // 写入图像文件
        Imgcodecs.imwrite(outputImageFile, image);

        // 显示图像
        HighGui.imshow("Processed Image", image);
       // HighGui.waitKey(0);
        HighGui.destroyAllWindows();
    }

    private static List<String> getOutputNames(Net net) {
        List<String> names = net.getLayerNames();
        List<String> outNames = new ArrayList<>();
        for (int unconnectedOutLayer : net.getUnconnectedOutLayers().toList()) {
            outNames.add(names.get(unconnectedOutLayer - 1));
        }
        return outNames;
    }

    private static void findObjects(List<Mat> outputs, Mat frame, List<String> classNames) {
        List<Integer> classIds = new ArrayList<>();
        List<Float> confidences = new ArrayList<>();
        List<Rect2d> boxes = new ArrayList<>();
        int width = frame.width();
        int height = frame.height();

        for (Mat output : outputs) {
            for (int i = 0; i < output.rows(); i++) {
                Mat row = output.row(i);
                Mat scores = row.colRange(5, output.cols());
                Core.MinMaxLocResult mm = Core.minMaxLoc(scores);
                float confidence = (float) mm.maxVal;
                if (confidence > 0.5) {
                    int centerX = (int) (row.get(0, 0)[0] * width);
                    int centerY = (int) (row.get(0, 1)[0] * height);
                    int w = (int) (row.get(0, 2)[0] * width);
                    int h = (int) (row.get(0, 3)[0] * height);
                    int x = centerX - w / 2;
                    int y = centerY - h / 2;

                    classIds.add((int) mm.maxLoc.x);
                    confidences.add(confidence);
                    boxes.add(new Rect2d(x, y, w, h));
                }
            }
        }

        if (boxes.isEmpty()) {
            return;
        }

        MatOfFloat confidencesMat = new MatOfFloat(Converters.vector_float_to_Mat(confidences));
        Rect2d[] boxesArray = boxes.toArray(new Rect2d[0]);
        MatOfRect2d boxesMat = new MatOfRect2d(boxesArray);
        MatOfInt indices = new MatOfInt();
        Dnn.NMSBoxes(boxesMat, confidencesMat, (float) 0.5f, (float) 0.4f, indices);

        for (int i = 0; i < indices.rows(); i++) {
            int idx = (int) indices.get(i, 0)[0];
            Rect2d box = boxesArray[idx];
            int classId = classIds.get(idx);
            String label = classNames.get(classId) + " " + String.format("%.2f", confidences.get(idx) * 100) + "%";

            Imgproc.rectangle(frame, box.tl(), box.br(), new Scalar(255, 0, 255), 2);
            Imgproc.putText(frame, label, box.tl(), Imgproc.FONT_HERSHEY_SIMPLEX, 0.6, new Scalar(255, 0, 255), 2);
        }
    }

视频物体识别


        // 读取coco.names文件
        String classesFile = "E:\\config\\coco.names";
        // 配置YOLO模型
        String modelConfiguration = "E:\\config\\yolov3.cfg";
        String modelWeights = "E:\\config\\yolov3.weights";
        // 打开视频
        VideoCapture cap = new VideoCapture("E:\\temp\\1.mp4");
        // 输出视频文件路径
        String outputVideoFile = "E:\\temp\\cache\\output_video.mp4";
        classNames.addAll(Files.readAllLines(Paths.get(classesFile)));

        Net net = Dnn.readNetFromDarknet(modelConfiguration, modelWeights);
        net.setPreferableBackend(Dnn.DNN_BACKEND_OPENCV);
        net.setPreferableTarget(Dnn.DNN_TARGET_CPU);

        if (!cap.isOpened()) {
            System.out.println("Error: Could not open video.");
            return;
        }

        // 获取视频帧的宽度和高度
        int frameWidth = (int) cap.get(Videoio.CAP_PROP_FRAME_WIDTH);
        int frameHeight = (int) cap.get(Videoio.CAP_PROP_FRAME_HEIGHT);
        int fps = (int) cap.get(Videoio.CAP_PROP_FPS);

        VideoWriter videoWriter = new VideoWriter(outputVideoFile, VideoWriter.fourcc('X', 'V', 'I', 'D'), fps, new Size(frameWidth, frameHeight), true);

        Mat frame = new Mat();

        while (cap.read(frame)) {
            if (frame.empty()) {
                break;
            }
            Mat blob = Dnn.blobFromImage(frame, 1 / 255.0, new Size(inpWidth, inpHeight), new Scalar(0, 0, 0), true, false);
            net.setInput(blob);

            List<Mat> result = new ArrayList<>();
            List<String> outBlobNames = getOutputNames(net);
            net.forward(result, outBlobNames);

            findObjects(result, frame);

            // 写入视频
            videoWriter.write(frame);


            // 显示图像
            HighGui.imshow("Processed Frame", frame);
            // 等待按键ESC
            if (HighGui.waitKey(10) == 27) {
                break;
            }
        }

        // 释放内存
        cap.release();
        videoWriter.release();
        HighGui.destroyAllWindows();
    }

    private static List<String> getOutputNames(Net net) {
        List<String> names = net.getLayerNames();
        List<String> outNames = new ArrayList<>();
        for (int unconnectedOutLayer : net.getUnconnectedOutLayers().toList()) {
            outNames.add(names.get(unconnectedOutLayer - 1));
        }
        return outNames;
    }

    private static void findObjects(List<Mat> outputs, Mat frame) {
        List<Integer> classIds = new ArrayList<>();
        List<Float> confidences = new ArrayList<>();
        List<Rect2d> boxes = new ArrayList<>();
        int width = frame.width();
        int height = frame.height();

        for (Mat output : outputs) {
            for (int i = 0; i < output.rows(); i++) {
                Mat row = output.row(i);
                Mat scores = row.colRange(5, output.cols());
                Core.MinMaxLocResult mm = Core.minMaxLoc(scores);
                float confidence = (float) mm.maxVal;
                if (confidence > confThreshold) {
                    int centerX = (int) (row.get(0, 0)[0] * width);
                    int centerY = (int) (row.get(0, 1)[0] * height);
                    int w = (int) (row.get(0, 2)[0] * width);
                    int h = (int) (row.get(0, 3)[0] * height);
                    int x = centerX - w / 2;
                    int y = centerY - h / 2;

                    classIds.add((int) mm.maxLoc.x);
                    confidences.add(confidence);
                    boxes.add(new Rect2d(x, y, w, h));
                }
            }
        }

        if (boxes.isEmpty()) {
            return;
        }

        MatOfFloat confidencesMat = new MatOfFloat(Converters.vector_float_to_Mat(confidences));
        Rect2d[] boxesArray = boxes.toArray(new Rect2d[0]);
        MatOfRect2d boxesMat = new MatOfRect2d(boxesArray);
        MatOfInt indices = new MatOfInt();
        Dnn.NMSBoxes(boxesMat, confidencesMat, (float) confThreshold, (float) nmsThreshold, indices);

        for (int i = 0; i < indices.rows(); i++) {
            int idx = (int) indices.get(i, 0)[0];
            Rect2d box = boxesArray[idx];
            int classId = classIds.get(idx);
            String label = classNames.get(classId) + " " + String.format("%.2f", confidences.get(idx) * 100) + "%";

            Imgproc.rectangle(frame, box.tl(), box.br(), new Scalar(255, 0, 255), 2);
            Imgproc.putText(frame, label, box.tl(), Imgproc.FONT_HERSHEY_SIMPLEX, 0.6, new Scalar(255, 0, 255), 2);
        }
    }

模型下载地址
点击这里
YOLOv3-416 就可以了
 

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值