Я использую 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 снимает фокус.
Я использовал HTTP : //192.168.1.8: 8080, но, к сожалению, я получаю сообщение «Не удалось открыть соединение с камерой ...». Я могу получить доступ к камере из браузера. – PRCube
try 'VideoCapture camera = new VideoCapture (" http: // <имя пользователя: пароль> @ /video.cgi?.mjpg ";' –
Adah
уже пробовал, что нет шансов. – PRCube