OpenCV Java [WARN:2] videoio(MSMF):无法抓取帧。错误:-1072875772

时间:2018-11-09 03:52:46

标签: java opencv javafx

我一直在尝试制作一个可以打开和关闭相机的简单应用程序。到目前为止,打开部分可以使用,但是每次我尝试关闭相机时,都会发生以下一系列事件:

  1. 捕获停止捕获,但是指示灯仍然亮着并且图像没有被清除。
  2. 第二次按下停止按钮,图像被清除。
  3. 之后,每当我按下开始按钮时,无论我是否执行了步骤2,它都不会执行任何操作,并给我以下错误提示:
  

[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();
        }
    }

这是我的控制器对象,有人可以帮助我找出问题所在吗?

3 个答案:

答案 0 :(得分:0)

由于硬件故障,我得到了完全相同的错误。我在Windows上,更新后停止工作。也可能是驱动程序问题。我强烈怀疑它起源于平台级别。 我更改了摄像头,一切恢复正常。

答案 1 :(得分:0)

我认为您的stopCamera方法需要capture.release()。

可能无关,但是我认为计时器是错误的方法。即使将摄像机设置为30 FPS,其流时钟与Java时序之间的偏差也会最终导致故障。而是在线程中使用无限循环,并知道capture.read()将挂起,直到有可用的帧为止。只要您有足够的处理能力可以跟上,无限循环就可以在任何FPS上正常工作。

答案 2 :(得分:0)

就我而言,我什至无法启动相机。这是因为“ Kaspersky Endpoint Security”在退出病毒防护程序后才开始工作。