如果使用 nu.pattern.OpenCV.loadShared() 加载 openCV,Java open CV 会卡在 VideoCapture 上以获取文件;

标签 java opencv ffmpeg javacv

我有一个来自 https://ratiler.wordpress.com/2014/09/08/detection-de-mouvement-avec-javacv/ 的示例代码使用 nu.pattern.OpenCV.loadShared(); 在静态 block 中加载打开的 cv 库的差异很小:

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.videoio.VideoCapture;
import org.opencv.imgproc.Imgproc;

public class JavaCVPrjt01 {
    static {
        //System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        nu.pattern.OpenCV.loadShared();
    }
    public static void main(String[] args) {
        JFrame jframe = new JFrame("HUMAN MOTION DETECTOR FPS");
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JLabel vidpanel = new JLabel();
        jframe.setContentPane(vidpanel);
        jframe.setSize(1280,720) ;
        jframe.setVisible(true);

        Mat frame = new Mat();
        Mat outerBox = new Mat();
        Size sz = new Size(1280,720);
        VideoCapture camera = new VideoCapture("D:/Downloads/video4.mp4");

        while (true) {
            if (camera.read(frame)) {
                Imgproc.resize(frame,frame, sz );
                outerBox = new Mat(frame.size(), CvType.CV_8UC1);
                Imgproc.cvtColor(frame, outerBox, Imgproc.COLOR_BGR2GRAY);
                Imgproc.GaussianBlur(outerBox, outerBox, new Size(3, 3), 0);

                ImageIcon image = new ImageIcon(Mat2bufferedImage(outerBox));
                vidpanel.setIcon(image);
                vidpanel.repaint();

            }
        }
    }

    public static BufferedImage Mat2bufferedImage(Mat image) {
        MatOfByte bytemat = new MatOfByte();
        Imgcodecs.imencode(".jpg", image, bytemat);
        byte[] bytes = bytemat.toArray();
        InputStream in = new ByteArrayInputStream(bytes);
        BufferedImage img = null;
        try {
            img = ImageIO.read(in);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return img;
    }

}
当然,还添加了所需的依赖项:
    <dependency>
        <groupId>org.bytedeco.javacpp-presets</groupId>
        <artifactId>opencv</artifactId>
        <version>3.2.0-1.3</version>
    </dependency>

    <dependency>
        <groupId>org.openpnp</groupId>
        <artifactId>opencv</artifactId>
        <version>3.2.0-1</version>
    </dependency>
所以,代码在之前执行
VideoCapture camera = new VideoCapture("D:/Downloads/video4.mp4");
它卡在哪里,我没有任何线索可以检查那里的 JNI 级别有什么问题。

最佳答案

这是一个许可问题,无法将 ffmpeg 包含到

 <dependency>
    <groupId>org.openpnp</groupId>
    <artifactId>opencv</artifactId>
    <version>3.2.0-1</version>
</dependency>
(看起来它出现在所有版本中,我已经尝试了所有可用的 maven)
https://github.com/openpnp/opencv/issues/55
UPD。
所以仍然需要显式加载 dll。就我而言
static {
        //System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        System.load("D:\\Downloads\\opencv\\build\\java\\x64\\opencv_java2411.dll");
        System.load("D:\\Downloads\\opencv\\build\\x64\\vc12\\bin\\opencv_ffmpeg2411_64.dll");     
    }
opencv_java 的显式加载和 opencv_ffmpeg成功了。未加载 opencv_ffmpeg明确的 VideoCapture's .read(frame)只是总是返回 false,没有提及任何丢失的原生 ffmpeg依赖问题。
以及 pom.xml 中所需的 java 依赖项是:
    <dependency>
        <groupId>org.bytedeco.javacpp-presets</groupId>
        <artifactId>opencv</artifactId>
        <version>2.4.11-0.11</version>
    </dependency>
    <dependency>
        <groupId>org.openpnp</groupId>
        <artifactId>opencv</artifactId>
        <version>2.4.11-2</version>
    </dependency>
(请不要我降级了opencv版本)

关于如果使用 nu.pattern.OpenCV.loadShared() 加载 openCV,Java open CV 会卡在 VideoCapture 上以获取文件;,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64128337/

相关文章:

java - 在 gradle 多模块项目中未复制 Jar 文件

java - Spring MVC 使用 ContentNegotiationManagerFactoryBean 仅返回 json 406

java - Selenium 日期选择器问题

python - OpenCV + OS X + 外部网络摄像头 = 非常慢

opencv - Affine-SIFT(ASIFT) 特征检测器

ffmpeg 在动画 GIF 的最后一帧减少时间延迟

java - 不同jar中的相同功能

c - OpenCV 可移植性

linux - 检查媒体分辨率,如果分辨率大,则ffmpeg,如果输出小于原始值,则删除原始值,否则删除输出

java - 使用 ffmpeg 编辑后的视频未显示在手机图库中