2015-07-25 2 views
1

Я фиксирую изображение с IP-камеры, и я работаю с кадрами. Моя программа читает, когда есть движение, а затем она делает фотографию и сохраняет ее на компьютере. Сначала он работает отлично, но когда он работает как 2-3 часа, он обычно получает ошибку, и я не нахожу объяснения этому. Потому что, если это ошибка при получении изображения или обработки, это должно произойти с самого начала, не так ли?Ошибка чтения с IP-камеры

Ошибки я получаю следующее:

Исключение в потоке "главный" java.lang.NullPointerException в com.googlecode.javacv.IPCameraFrameGrabber.grab (IPCameraFrameGrabber.java:105) в Llamada .main (Llamada.java:34)

Я искал ошибку nº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(); 
} 
} 

Спасибо за все!

ответ

0

Вы пытались использовать отладчик и устанавливали точку останова? Я понимаю, что ждать 2-3 часа - это не весело, но, возможно, это поможет вам разобраться в происходящем.

Это похоже на вторую условную часть петли while. Что-то внутри метода grab на объекте grabber бросает NullPointerException.

Возможно, способ, которым вы инициализировали граббер, привел его к этому.

И было бы полезно узнать, какую версию класса IPCameraFrameGrabber вы используете и что автор этого класса действительно ожидал. А именно, он инициализируется для ответа на конкретный URL-адрес камеры. При чтении class, похоже, это не претендует на работу со всеми потоками MJPEG для IP-камер.

Давайте рассмотрим один пример комментария там:

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 

И сравните, что ваш URL:

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

Я собираю это не Foscam videostream.cgi URL, ни андроид IPcam videofeed url, которые, по-видимому, будут единственными проверенными URL-адресами. Это напоминает мне URL-адрес камеры Axis. Об этом позже.

В recent version этого класса (также в старшем один на самом деле), кажется, есть некоторый хак попытка только чтение до конца подзаголовка, который всегда с разделителями по круЛ.Ф.крlf, который мог бы быть выполнен также с буферизованным считывающим устройством ввода, пока он не получит пустую строку.То, что я вижу здесь, что, кажется, скорее всего, вызовет NPE является:

  • Когда ответ Вашего URL в HTTP-сервере не содержит content-length заголовка, который вполне возможно, возвращенный readImage()byte[]is null.

С javax.imageio.ImageIO указывает, что он будет бросать IllegalArgumentException, когда он получает null вход, я предполагаю, что это ByteArrayInputStream конструктор в grabBufferedImage метод, который бросает это, IplImage.createFrom(null) in the old version или b.length in the newer version то есть.

Ни один из номеров строк этих версий не совпадает с сообщением об ошибке, которое вы указали, что вы получаете, поэтому, возможно, ваша версия библиотеки еще раз отличается и сломана по-разному. Попробуйте использовать отладчик, отредактируйте и исправьте источник IPCameraFrameGrabber, чтобы лучше поддерживать ваш mjpeg через http-устройство, основанное на том, что вы узнаете, действительно во входном потоке ответа HTTP.

Поскольку формат URL напоминает мне камеры компании Axis, я попытался это с одной бегущий прошивки v5.50 с сервером боа построен в:

$ curl -I http://user:[email protected]: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 

Таким образом, вы можете увидеть, длина содержимого отсутствует там. Тем не менее, вы говорите, что вы получаете кадры изначально в течение нескольких часов, а затем, так что я немного растерялся с этой частью. Я имею в виду, что это звучит так, как если бы поток ввода закрывался, или реализация Java-оболочки, обтекающая поток, реализованная в обработчике протокола HTTP, по какой-то причине исчерпывает какое-то общее пространство или таймер открытого подключения. Я знаю, что это кажется расплывчатым.

Еще одна вещь, которая кажется странной, заключается в том, что из того, что я прочитал в двух примерах классов, связанных с IPCameraFrameGrabber, каждый вызов для захвата считывает входной поток, который ищет заголовки сначала, что не имеет для меня смысла прямо сейчас, и я чувствую, что я, должно быть, неправильно понимаю это.

+0

Итак, если я инициализирую граббер за пределами основного, как статический, может ли он решить проблему? Я не уверен, почему инициализация влияет на вызов метода grab. –

+0

Трудно сказать, допустим, что класс не ожидал, что вы его инициализируете так, как у вас есть; это не ясно документировано, что может и не может быть передано для его инициализации. Поэтому я просматриваю: https://code.google.com/p/javacv/source/browse/src/main/java/com/googlecode/javacv/IPCameraFrameGrabber.java?r=0e399872bfeb3824e975b3c575ad3a0a41027dee, а его строка 105 даже не что-то, что вызовет исключение. Можете ли вы начать с обновления вашей зависимости от этой библиотеки? – dlamblin

+0

В методе начала есть код, который комментируется как «хрупкий», а в методе grabBufferedImage есть захватывающие вызовы, которые могут его выбросить. Я пытаюсь помочь, но ваша проблема, скорее всего, связана с ожиданиями этой библиотеки, которую вы используете, и несоответствие с тем, что делает ваша IP-камера на самом деле, которая не была проверена оригинальным автором (ами) , – dlamblin

Смежные вопросы