我刚刚开始在java中学习openCV,我已经设置了我的Eclipse IDE以及所有OpenCV java依赖项。
现在我手头有一项任务从我以.avi文件格式录制的视频文件中提取单帧。
我从这个link搜索并使用下面给出的代码,
package vasanth;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.highgui.Highgui;
import org.opencv.highgui.VideoCapture;
public class Vasanth {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
VideoCapture camera = new VideoCapture("G:\\PICTURES\\roxtar vassy\\early days in APSCE.wmv");
/* if(!camera.isOpened()){
System.out.println("Error");
} */
Mat frame = new Mat();
while(true){
System.out.println("Looping.. \n");
if (camera.read(frame)){
System.out.println("Frame Obtained");
System.out.println("Captured Frame Width " +
frame.width() + " Height " + frame.height());
Highgui.imwrite("camera.jpg", frame);
System.out.println("OK");
break;
}
}
}
}
当我执行此操作时,程序在此行无限循环
camera.read(frame)
我也尝试在没有循环的情况下运行此代码,并成功获取了我的系统上的camera.jpg文件,但该文件已损坏。 据我所知,这个框架没有完全用所有像素提取,因此看起来已经损坏了。
所以这里的问题是为什么camera.read(frame)总是返回false而循环永远不会中断?
我等了10多分钟。 我想要做的就是提取一个单独的帧,这种方法不会发生。
根据我在google上搜索的内容,我知道有一个名为ffmpeg的工具,它将视频文件作为输入并给我帧。 但是我希望用我在Eclipse上运行的java代码为启动器实现这个功能。
答案 0 :(得分:0)
在复制你的问题时我遇到了几个问题,所以让我引导你完成它们。
首先,您使用旧版本的框架。目前的是3.2,所以考虑升级。我使用的是最新版本。
你不应该注释camera.isOpened()
检查,因为如果没有打开相机,就没有意义继续。我认为,你的应用无法通过该检查,所以你决定跳过那个:)但是为了正确打开相机你应该this或this。第一个链接适用于我(唯一的变化是3.2版本的路径是\opencv\build\x64\vc14\bin
,我不得不重新启动计算机)
代码与目前几乎完全相同,只是最新版本的差异:
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.videoio.VideoCapture;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
import java.nio.file.Paths;
public class Vasanth {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
String filePath = "G:\\PICTURES\\roxtar vassy\\early days in APSCE.wmv";
if (!Paths.get(filePath).toFile().exists()){
System.out.println("File " + filePath + " does not exist!");
return;
}
VideoCapture camera = new VideoCapture(filePath);
if (!camera.isOpened()) {
System.out.println("Error! Camera can't be opened!");
return;
}
Mat frame = new Mat();
while(true){
if (camera.read(frame)){
System.out.println("Frame Obtained");
System.out.println("Captured Frame Width " +
frame.width() + " Height " + frame.height());
Imgcodecs.imwrite("camera.jpg", frame);
System.out.println("OK");
break;
}
}
BufferedImage bufferedImage = matToBufferedImage(frame);
showWindow(bufferedImage);
camera.release();
}
private static BufferedImage matToBufferedImage(Mat frame) {
int type = 0;
if (frame.channels() == 1) {
type = BufferedImage.TYPE_BYTE_GRAY;
} else if (frame.channels() == 3) {
type = BufferedImage.TYPE_3BYTE_BGR;
}
BufferedImage image = new BufferedImage(frame.width(), frame.height(), type);
WritableRaster raster = image.getRaster();
DataBufferByte dataBuffer = (DataBufferByte) raster.getDataBuffer();
byte[] data = dataBuffer.getData();
frame.get(0, 0, data);
return image;
}
private static void showWindow(BufferedImage img) {
JFrame frame = new JFrame();
frame.getContentPane().add(new JLabel(new ImageIcon(img)));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(img.getWidth(), img.getHeight() + 30);
frame.setTitle("Image captured");
frame.setVisible(true);
}
}
注意,为了证明这段代码有用,我使用简单的Swing JFrame:
答案 1 :(得分:0)
我面临着同一问题,即camera.isOpened()返回false。 这就是我解决的方法。
String filePath = "C:\\Aslam_Face_Detection.mp4";
VideoCapture camera = new VideoCapture(filePath);
camera.open(filePath); // This is the line I added
camera.isOpened(); // returns true. worked.