Java open CV hangs on VideoCapture for file if openCV is loaded with nu.pattern.OpenCV.loadShared();

huangapple go评论116阅读模式
英文:

Java open CV hangs on VideoCapture for file if openCV is loaded with nu.pattern.OpenCV.loadShared();

问题

以下是您提供的代码的翻译部分:

我从 https://ratiler.wordpress.com/2014/09/08/detection-de-mouvement-avec-javacv/ 获取了一个示例代码,与在静态块中使用 `nu.pattern.OpenCV.loadShared();` 加载 open 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 级别的问题。

英文:

I have a sample code from https://ratiler.wordpress.com/2014/09/08/detection-de-mouvement-avec-javacv/ with small difference in loading the open cv library in the static block using nu.pattern.OpenCV.loadShared(); :

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(&quot;HUMAN MOTION DETECTOR FPS&quot;);
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(&quot;D:/Downloads/video4.mp4&quot;);
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(&quot;.jpg&quot;, 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;
}
}

and of course, the needed dependencies were added:

    &lt;dependency&gt;
&lt;groupId&gt;org.bytedeco.javacpp-presets&lt;/groupId&gt;
&lt;artifactId&gt;opencv&lt;/artifactId&gt;
&lt;version&gt;3.2.0-1.3&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.openpnp&lt;/groupId&gt;
&lt;artifactId&gt;opencv&lt;/artifactId&gt;
&lt;version&gt;3.2.0-1&lt;/version&gt;
&lt;/dependency&gt;

so, code is executed right before

VideoCapture camera = new VideoCapture(&quot;D:/Downloads/video4.mp4&quot;);

where it hangs and I have no clues to check what is wrong on the JNI level there.

答案1

得分: 0

以下是翻译好的内容:

这是一个许可问题,导致无法将ffmpeg包含到以下依赖中:

<dependency>
    <groupId>org.openpnp</groupId>
    <artifactId>opencv</artifactId>
    <version>3.2.0-1</version>
</dependency>

(看起来在所有版本中都出现了这个问题,我已经尝试了Maven中所有可用的版本)

链接:https://github.com/openpnp/opencv/issues/55

更新:

因此仍然需要显式加载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_javaopencv_ffmpeg 即可解决问题。如果不显式加载 opencv_ffmpegVideoCapture.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的版本)

英文:

It was a licensing issue that made impossible to include ffmpeg to

 &lt;dependency&gt;
&lt;groupId&gt;org.openpnp&lt;/groupId&gt;
&lt;artifactId&gt;opencv&lt;/artifactId&gt;
&lt;version&gt;3.2.0-1&lt;/version&gt;
&lt;/dependency&gt;

(and it looks like it occurs in all versions, I have tried all available in maven)

https://github.com/openpnp/opencv/issues/55

UPD.

so it is still required to load dlls explicitly. In my case

static {
//System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
System.load(&quot;D:\\Downloads\\opencv\\build\\java\\x64\\opencv_java2411.dll&quot;);
System.load(&quot;D:\\Downloads\\opencv\\build\\x64\\vc12\\bin\\opencv_ffmpeg2411_64.dll&quot;);     
}

explicit load of opencv_java and opencv_ffmpeg made the trick. Without loading opencv_ffmpeg explicitly the VideoCapture&#39;s .read(frame) was just always returning false with no any mention on any missing native ffmpeg dependency problem.

And the required java dependencies in pom.xml are:

    &lt;dependency&gt;
&lt;groupId&gt;org.bytedeco.javacpp-presets&lt;/groupId&gt;
&lt;artifactId&gt;opencv&lt;/artifactId&gt;
&lt;version&gt;2.4.11-0.11&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.openpnp&lt;/groupId&gt;
&lt;artifactId&gt;opencv&lt;/artifactId&gt;
&lt;version&gt;2.4.11-2&lt;/version&gt;
&lt;/dependency&gt;

(please not i have downgraded the opencv version)

huangapple
  • 本文由 发表于 2020年9月30日 06:11:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/64128337.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定