2016-03-11 2 views
3

Я использую OpenCV для обработки изображения камеры, однако на данный момент я использую веб-камеру USB, подключенную к компьютеру. Мне было интересно, можно ли внести изменения в мой текущий код для потоковой передачи видео с IP-адреса.Потоковая передача с IP-камеры с использованием OpenCV

startCamera метод открывает камеру.

Код:

public class ObjRecognitionController { 
// FXML camera button 
@FXML 
private Button cameraButton; 
// the FXML area for showing the current frame 
@FXML 
private ImageView originalFrame; 
// the FXML area for showing the mask 
@FXML 
private ImageView maskImage; 
// the FXML area for showing the output of the morphological operations 
@FXML 
private ImageView morphImage; 
// FXML slider for setting HSV ranges 
@FXML 
private Slider hueStart; 
@FXML 
private Slider hueStop; 
@FXML 
private Slider saturationStart; 
@FXML 
private Slider saturationStop; 
@FXML 
private Slider valueStart; 
@FXML 
private Slider valueStop; 
// FXML label to show the current values set with the sliders 
@FXML 
private Label hsvCurrentValues; 

// a timer for acquiring the video stream 
private ScheduledExecutorService timer; 
// the OpenCV object that performs the video capture 
private VideoCapture capture = new VideoCapture(); 
// a flag to change the button behavior 
private boolean cameraActive; 

// property for object binding 
private ObjectProperty<String> hsvValuesProp; 

/** 
* The action triggered by pushing the button on the GUI 
*/ 
@FXML 
private void startCamera() 
{ 
    // bind a text property with the string containing the current range of 
    // HSV values for object detection 
    hsvValuesProp = new SimpleObjectProperty<>(); 
    this.hsvCurrentValues.textProperty().bind(hsvValuesProp); 

    // set a fixed width for all the image to show and preserve image ratio 
    this.imageViewProperties(this.originalFrame, 400); 
    this.imageViewProperties(this.maskImage, 200); 
    this.imageViewProperties(this.morphImage, 200); 

    if (!this.cameraActive) { 
     // start the video capture 
     this.capture.open(0); 

     // is the video stream available? 
     if (this.capture.isOpened()) { 
      this.cameraActive = true; 

      // grab a frame every 33 ms (30 frames/sec) 
      Runnable frameGrabber = new Runnable() { 

       @Override 
       public void run() { 
        Image imageToShow = grabFrame(); 
        originalFrame.setImage(imageToShow); 
       } 
      }; 

      this.timer = Executors.newSingleThreadScheduledExecutor(); 
      this.timer.scheduleAtFixedRate(frameGrabber, 0, 33, TimeUnit.MILLISECONDS); 

      // update the button content 
      this.cameraButton.setText("Stop Camera"); 
     } else { 
      // log the error 
      System.err.println("Failed to open the camera connection..."); 
     } 
    } else { 
     // the camera is not active at this point 
     this.cameraActive = false; 
     // update again the button content 
     this.cameraButton.setText("Start Camera"); 

     // stop the timer 
     try { 
      this.timer.shutdown(); 
      this.timer.awaitTermination(33, TimeUnit.MILLISECONDS); 
     } catch (InterruptedException e) { 
      // log the exception 
      System.err.println("Exception in stopping the frame capture, trying to release the camera now... " + e); 
     } 

     // release the camera 
     this.capture.release(); 
    } 
} 

/** 
* Get a frame from the opened video stream (if any) 
* 
* @return the {@link Image} to show 
*/ 
private Image grabFrame() 
{ 
    // init everything 
    Image imageToShow = null; 
    Mat frame = new Mat(); 

    // 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()) 
      { 
       // init 
       Mat blurredImage = new Mat(); 
       Mat hsvImage = new Mat(); 
       Mat mask = new Mat(); 
       Mat morphOutput = new Mat(); 

       // remove some noise 
       Imgproc.blur(frame, blurredImage, new Size(7, 7)); 

       // convert the frame to HSV 
       Imgproc.cvtColor(blurredImage, hsvImage, Imgproc.COLOR_BGR2HSV); 

       // get thresholding values from the UI 
       // remember: H ranges 0-180, S and V range 0-255 
       Scalar minValues = new Scalar(this.hueStart.getValue(), this.saturationStart.getValue(), 
         this.valueStart.getValue()); 
       Scalar maxValues = new Scalar(this.hueStop.getValue(), this.saturationStop.getValue(), 
         this.valueStop.getValue()); 

       // show the current selected HSV range 
       String valuesToPrint = "Hue range: " + minValues.val[0] + "-" + maxValues.val[0] 
         + "\tSaturation range: " + minValues.val[1] + "-" + maxValues.val[1] + "\tValue range: " 
         + minValues.val[2] + "-" + maxValues.val[2]; 
       this.onFXThread(this.hsvValuesProp, valuesToPrint); 

       // threshold HSV image to select tennis balls 
       Core.inRange(hsvImage, minValues, maxValues, mask); 
       // show the partial output 
       this.onFXThread(this.maskImage.imageProperty(), this.mat2Image(mask)); 

       // morphological operators 
       // dilate with large element, erode with small ones 
       Mat dilateElement = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(24, 24)); 
       Mat erodeElement = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(12, 12)); 

       Imgproc.erode(mask, morphOutput, erodeElement); 
       Imgproc.erode(mask, morphOutput, erodeElement); 

       Imgproc.dilate(mask, morphOutput, dilateElement); 
       Imgproc.dilate(mask, morphOutput, dilateElement); 

       // show the partial output 
       this.onFXThread(this.morphImage.imageProperty(), this.mat2Image(morphOutput)); 

       // find the tennis ball(s) contours and show them 
       frame = this.findAndDrawBalls(morphOutput, frame); 

       // convert the Mat object (OpenCV) to Image (JavaFX) 
       imageToShow = mat2Image(frame); 
      } 

     } 
     catch (Exception e) 
     { 
      // log the (full) error 
      System.err.print("ERROR"); 
      e.printStackTrace(); 
     } 
    } 

    return imageToShow; 
} 

/** 
* Given a binary image containing one or more closed surfaces, use it as a 
* mask to find and highlight the objects contours 
* 
* @param maskedImage 
*   the binary image to be used as a mask 
* @param frame 
*   the original {@link Mat} image to be used for drawing the 
*   objects contours 
* @return the {@link Mat} image with the objects contours framed 
*/ 
private Mat findAndDrawBalls(Mat maskedImage, Mat frame) { 
    // init 
    List<MatOfPoint> contours = new ArrayList<>(); 
    Mat hierarchy = new Mat(); 
    // find contours 
    Imgproc.findContours(maskedImage, contours, hierarchy, Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_SIMPLE); 

    // if any contour exist... 
    if (hierarchy.size().height > 0 && hierarchy.size().width > 0) { 
     // for each contour, display it in yellow 
     for (int idx = 0; idx >= 0; idx = (int) hierarchy.get(0, idx)[0]) { 
      Imgproc.drawContours(frame, contours, idx, new Scalar(0, 255, 255),2); 

      Rect rect = Imgproc.boundingRect(contours.get(idx)); 

      if(rect.x < 25){ 
       System.out.println("Turn left " + rect.x); 
      }else if(rect.x > 600){ 
       System.out.println("Turn Right: " + rect.x); 
      } 
      System.out.println(); 
     } 
    } 

    return frame; 
} 

/** 
* Set typical {@link ImageView} properties: a fixed width and the 
* information to preserve the original image ration 
* 
* @param image 
*   the {@link ImageView} to use 
* @param dimension 
*   the width of the image to set 
*/ 
private void imageViewProperties(ImageView image, int dimension) { 
    // set a fixed width for the given ImageView 
    image.setFitWidth(dimension); 
    // preserve the image ratio 
    image.setPreserveRatio(true); 
} 

/** 
* Convert a {@link Mat} object (OpenCV) in the corresponding {@link Image} 
* for JavaFX 
* 
* @param frame 
*   the {@link Mat} representing the current frame 
* @return the {@link Image} to show 
*/ 
private Image mat2Image(Mat frame) { 
    // create a temporary buffer 
    MatOfByte buffer = new MatOfByte(); 
    // encode the frame in the buffer, according to the PNG format 
    Imgcodecs.imencode(".png", frame, buffer); 
    // build and return an Image created from the image encoded in the 
    // buffer 
    return new Image(new ByteArrayInputStream(buffer.toArray())); 
} 

/** 
* Generic method for putting element running on a non-JavaFX thread on the 
* JavaFX thread, to properly update the UI 
* 
* @param property 
*   a {@link ObjectProperty} 
* @param value 
*   the value to set for the given {@link ObjectProperty} 
*/ 
private <T> void onFXThread(final ObjectProperty<T> property, final T value) 
{ 
    Platform.runLater(new Runnable() { 

     @Override 
     public void run() 
     { 
      property.set(value); 
     } 
    }); 
} 

}

Документация камеры

VLC Media Player VLC Media Player является видеоплеер кросс-платформенный, потокового сервера и конвертер решение в одиночный упаковка. Получи это здесь.

Для использования веб-камеры с мультимедиа-плеером VLC в меню выберите «Медиа» ⇨ «Открыть сетевой поток» и введите http://192.168.1.8:8080/video для потокового видео или http://192.168.1.8:8080/audio.wav для потоковой передачи аудио.

Вы также можете использовать VLC Media Player для записи видео:

Select Media -> Convert/Save. Выберите Сеть Вкладка Введите http://192.168.1.8:8080/video в качестве URL Нажмите кнопку Преобразовать/сохранить Выберите файл назначения, формат, в котором вы хотите сохранить, и вы хорошо идти ZoneMinder Используйте эту конфигурацию:

Общее: Источник Тип: Удаленный Функция: Монитор

Источник: Протокол: HTTP Метод: Простое имя Ведущий: 192.168.1.8 Порт: 8080 Путь удаленного хоста:/видео (просто «видео» не работает).

Примечание: При необходимости укажите свое имя пользователя в пароле по URL-адресу, например: username: [email protected]

Blue Iris Открыть «Добавить камеру» диалог как обычно

При использовании IP-камеры, вы должны выбрать «MJPEG поток» из списка вместо конкретной камеры.

путь Видео:/видео аудио путь: /audio.wav имя Ведущий: 192.168.1.8 Порт: 8080 Это не имеет значения, что вы входите в поле «RTSP/видео порт».

WebcamXP В главном интерфейсе WebcamXP, щелкните правой кнопкой мыши на видео источника и выберите Сетевые камеры ⇨ Connect ...

Набор камеры Марка для Android и Модель камеры для IP-камеры. Выберите желаемый пресет (рекомендуется MJPEG). Нажмите "Далее.

Установить имя хоста 192.168.1.8 и порт до 8080.

Нажмите «ОК», и вы готовы использовать свою новую камеру!

Расширенный Вот список сервисных адресов IP Webcam:

http://192.168.1.8:8080/video является URL MJPEG. http://192.168.1.8:8080/shot.jpg извлекает последний кадр. http://192.168.1.8:8080/audio.wav - это аудиопоток в формате Wav. http://192.168.1.8:8080/audio.aac - это аудиопоток в формате AAC (если поддерживается аппаратным обеспечением). http://192.168.1.8:8080/audio.opus - это аудиопоток в формате Opus. http://192.168.1.8:8080/focus фокусирует камеру. http://192.168.1.8:8080/nofocus снимает фокус.

ответ

1

Вы можете просто изменить

VideoCapture camera = new VideoCapture("IPADDRESS"); 

или

capture.open("IPADRESS"); 
+0

Я использовал HTTP : //192.168.1.8: 8080, но, к сожалению, я получаю сообщение «Не удалось открыть соединение с камерой ...». Я могу получить доступ к камере из браузера. – PRCube

+0

try 'VideoCapture camera = new VideoCapture (" http: // <имя пользователя: пароль> @ /video.cgi?.mjpg ";' – Adah

+1

уже пробовал, что нет шансов. – PRCube

1

Вы должны захватить видео из потока URL камеры, как

VideoCapture capture = new VideoCapture(url); 

URL-адрес может быть

url = "http://IPADDRESS:PORT/?dummy=param.mjpg" 
//or 
url= "http://IPADDRESS:PORT/mjpeg.cgi"; 
//or 
url = "http://IPADDRESS:PORT/mjpg/mjpeg.cgi"; 
//or 
url ="http://IPADDRESS:PORT/video.mjpeg"; 

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

Также вместо использования IP веб-приложения с OpenCV упаковывают вы используете андроид устройства, Лучшей альтернативой является использование droidcam приложения и программное обеспечение для ПК распознавать веб-камеру, как

VideoCapture capture = new VideoCapture(camIndex); 
+0

Ни одна из этих работ. через браузер, мне нужно только ввести 192.168.1.8:8080. – PRCube

+1

теперь попробуйте скопировать полный url, предоставленный браузером, url должен заканчиваться либо '.mjpeg, .cgi, .mjpg, и т.д' в зависимости от камеры. –

+0

url не имеет расширения, это просто http://192.168.1.8:8080, который напрямую скопирован из строки url. Я выяснил, что он предоставляет специальный URL-адрес для VLC-плеера, который является http: //192.168. 1.8: 8080/video, и он отлично работает с VLC, но не работает с моим кодом. – PRCube

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