我一直在尝试制作一个可以打开和关闭相机的简单应用程序。到目前为止,打开部分可以使用,但是每次我尝试关闭相机时,都会发生以下一系列事件:
[WARN:1] videoio(MSMF):调用OnReadSample()并显示错误状态: -1072875772 [WARN:1] videoio(MSMF):异步ReadSample()调用失败,错误状态为:-1072875772 [WARN:2] videoio(MSMF):无法抓取 帧。错误:-1072875772
package application;
import java.io.ByteArrayInputStream;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.videoio.VideoCapture;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
public class FXHelloCVController {
@FXML
private AnchorPane MainPane;
@FXML
private Button StartButton;
@FXML
private ImageView currentFrame;
@FXML
private Button StopButton;
private ScheduledExecutorService timer;
private VideoCapture capture = new VideoCapture();
private boolean cameraActive = false;
private static int cameraID = 0;
@FXML
void startCamera(ActionEvent event) {
if(!this.cameraActive) {
//if the camera is not active, open the camera
cameraActive = true;
this.capture.open(cameraID);
if(this.capture.isOpened()) {
//if the stream is available, run at 30fps (33 ms)
Runnable frameGrabber = new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
Image imageToShow = grabFrame();
Platform.runLater(new Runnable() {
@Override public void run() {
currentFrame.setImage(imageToShow); }
});
}
};
this.timer = Executors.newSingleThreadScheduledExecutor();
this.timer.scheduleAtFixedRate(frameGrabber, 0, 33,
TimeUnit.MILLISECONDS);
}
}
}
private Image grabFrame() {
// TODO Auto-generated method stub
Mat frame = new Mat();
MatOfByte buffer = new MatOfByte();
// check if the capture is open
if (this.capture.isOpened()){
try{
// read the current frame
this.capture.read(frame);
// if the frame is not empty, process it
if (!frame.empty()){
Imgcodecs.imencode(".png", frame, buffer);
}
}catch(Exception e){
// log the error
System.err.println("Exception during the image elaboration: " +
e);
}
}
return new Image(new ByteArrayInputStream(buffer.toArray()));
}
@FXML
private void stopCamera(){
cameraActive = false;
if (this.timer!=null && !this.timer.isShutdown()){
try{
// stop the timer
this.timer.awaitTermination(33, TimeUnit.MILLISECONDS);
this.timer.shutdown();
this.currentFrame.setImage(null);
}catch (InterruptedException e){
e.printStackTrace();
}
}
这是我的控制器对象,有人可以帮助我找出问题所在吗?
答案 0 :(得分:0)
由于硬件故障,我得到了完全相同的错误。我在Windows上,更新后停止工作。也可能是驱动程序问题。我强烈怀疑它起源于平台级别。 我更改了摄像头,一切恢复正常。
答案 1 :(得分:0)
我认为您的stopCamera方法需要capture.release()。
可能无关,但是我认为计时器是错误的方法。即使将摄像机设置为30 FPS,其流时钟与Java时序之间的偏差也会最终导致故障。而是在线程中使用无限循环,并知道capture.read()将挂起,直到有可用的帧为止。只要您有足够的处理能力可以跟上,无限循环就可以在任何FPS上正常工作。
答案 2 :(得分:0)
就我而言,我什至无法启动相机。这是因为“ Kaspersky Endpoint Security”在退出病毒防护程序后才开始工作。