从IP摄像机读取时出错

时间:2015-07-25 18:35:20

标签: eclipse javacv opencv3.0

我从IP摄像头捕获图像,然后使用帧。我的程序在有动作时读取,然后,它会制作照片并将其保存在计算机上。 它起初工作得很好,但是当它运行2-3个小时时,它通常会出错,我没有找到解释。因为,如果在获取图像或处理时出错,它应该首先发生,不应该发生吗?

我得到的错误是下一个:

  

线程“main”java.lang.NullPointerException中的异常       在com.googlecode.javacv.IPCameraFrameGrabber.grab(IPCameraFrameGrabber.java:105)       在Llamada.main(Llamada.java:34)

我找了第105号错误,但我没找到任何东西。

该计划是下一个:

public class Llamada {
public static void main(String[] args) throws Exception {
    IPCameraFrameGrabber grabber = new IPCameraFrameGrabber("http://192.168.2.102:80/mjpg/video.mjpg");
    //OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
    grabber.start();

    IplImage frame = grabber.grab();
    IplImage image = null;
    IplImage prevImage = null;
    IplImage diff = null;

    Date data = new Date();
    String output = "";

    int i=0, j=0;

    CanvasFrame canvasFrame = new CanvasFrame("IP Camera");
    canvasFrame.setCanvasSize(frame.width(), frame.height());

    CvMemStorage storage = CvMemStorage.create();

    while (canvasFrame.isVisible() && (frame = grabber.grab()) != null) {
        cvSmooth(frame, frame, CV_GAUSSIAN, 9, 9, 2, 2);
        if (image == null) {
            image = IplImage.create(frame.width(), frame.height(), IPL_DEPTH_8U, 1);
            cvCvtColor(frame, image, CV_RGB2GRAY);
        } else {
            prevImage = IplImage.create(frame.width(), frame.height(), IPL_DEPTH_8U, 1);
            prevImage = image;
            image = IplImage.create(frame.width(), frame.height(), IPL_DEPTH_8U, 1);
            cvCvtColor(frame, image, CV_RGB2GRAY);
        }

        if (diff == null) {
            diff = IplImage.create(frame.width(), frame.height(), IPL_DEPTH_8U, 1);
        }

        if (prevImage != null) {
            // perform ABS difference
            cvAbsDiff(image, prevImage, diff);
            // do some threshold for wipe away useless details
            cvThreshold(diff, diff, 64, 255, CV_THRESH_BINARY);

            canvasFrame.showImage(diff);

            // recognize contours
            CvSeq contour = new CvSeq(null);
            cvFindContours(diff, storage, contour, Loader.sizeof(CvContour.class), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);



            while (contour != null && !contour.isNull()) {
                if (contour.elem_size() > 0) {

                    output = data.toString();

                    if (data != null)
                        output = output.substring(0,10);

                    if(i%300 == 0)
                         cvSaveImage((j++)+" "+ output +"-capture.jpg", frame);


                    CvBox2D box = cvMinAreaRect2(contour, storage);
                    // test intersection
                    if (box != null) {
                        CvPoint2D32f center = box.center();
                        CvSize2D32f size = box.size();

                    }
                    i++;
                }
                contour = contour.h_next();
            }
        }
    }
    grabber.stop();
    canvasFrame.dispose();
}
}

谢谢你的一切!

1 个答案:

答案 0 :(得分:0)

您是否尝试过使用调试器并设置断点?我知道等待2-3个小时并不好玩,但也许它可以帮助你理解正在发生的事情。

这似乎是在while循环的第二个条件部分。 grab对象上方法grabber内的某些内容正在抛出NullPointerException

你初步掌握抓取器的方式可能导致它做到这一点。

了解您正在使用的IPCameraFrameGrabber类的哪个版本以及该类的作者真正期望的内容将会很有用。即,它已初始化为响应特定相机的网址。在阅读class时,似乎没有声称可以使用所有IP摄像机' MJPEG流。

让我们看看那里的一个例子评论:

foscam url http://host/videostream.cgi?user=username&pwd=password
           http://192.168.0.59:60/videostream.cgi?user=admin&pwd=password
android ipcam http://192.168.0.57:8080/videofeed

并将其与您的网址进行比较:

http://192.168.2.102:80/mjpg/video.mjpg

我收集它不是一个foscam videostream.cgi网址,也不是一个android ipcam视频网址,这似乎是唯一经过测试的网址。它让我想起了一个安讯士相机网址。稍后会详细介绍。

在该类的recent version中(实际上也是在较旧的类中),似乎有一些黑客尝试只读到一个总是由 cr lf cr lf 这可能与缓冲输入读取器读取线一样,直到它变为空行。我在这里看到的似乎可能导致npe的是:

  • 如果您的网址的http服务器响应中不包含content-length标头,则很可能会返回readImage() byte[] is null

由于javax.imageio.ImageIO指定在获得IllegalArgumentException输入时会抛出null,因此我猜测它是ByteArrayInputStream中的grabBufferedImage构造函数引发此问题的IPCameraFrameGrabber方法,IplImage.createFrom(null) in the old versionb.length in the newer version

这些版本的行号都没有显示您已经显示的错误消息,因此您的版本库可能会再次出现异议,并且会有所不同。尝试使用调试器,编辑和修补$ curl -I http://user:pass@10.10.10.10:8080/mjpg/video.mjpg HTTP/1.0 200 OK Cache-Control: no-cache Pragma: no-cache Expires: Thu, 01 Dec 1994 16:00:00 GMT Connection: close Content-Type: multipart/x-mixed-replace; boundary=myboundary 的来源,以更好地支持您的mjpeg over http" device"根据您发现的内容确实存在于http响应的输入流中。

由于url格式让我想起了Axis相机,我尝试使用内置boa服务器的一个正在运行的固件v5.50:

IPCameraFrameGrabber

所以你可以看到那里缺少内容长度。但是,你确实说你最初需要几个小时的帧,然后才开始,所以我对这个部分感到很茫然。我的意思是听起来好像输入流已经关闭,或者在http协议处理程序中实现的包装流的java实现由于某种原因用完某种总空间或打开连接计时器。我知道这看起来很模糊。

另一件看似奇怪的事情是,从我在for (var i in arr) { var trimmed = arr[i].trim(); if (trimmed .length !== 0) { names.push(trimmed); } } 链接的两个示例类中读到的内容,每次调用grab都会先读取输入流,然后查找标题,这对我来说没有意义现在,我觉得我必须误解这一点。