Java OpenCV — это мощная библиотека компьютерного зрения с открытым исходным кодом, которая обеспечивает богатые функции обработки и анализа изображений. Все больше и больше приложений требуют использования камер для получения видеопотоков в реальном времени для обработки и анализа.
Основные шаги по открытию камеры с помощью OpenCV в Java следующие:
Адрес загрузки: https://opencv.org/releases.
Загрузите версию, подходящую для вашей операционной системы, с официального сайта OpenCV, а затем дважды щелкните ее, чтобы установить (по сути распаковав). После распаковки откройте папку:
build/
sources/
LICENSE.txt
LICENSE_FFMPEG.txt
README.md.txt
build — это некоторые библиотечные файлы, которые используются при использовании OpenCV, а источники — это некоторые демонстрационные примеры исходных кодов, которые OpenCV официально предоставляет нам.
Вам не нужно настраивать переменные среды. Вы можете использовать их напрямую. dll(opencv_java411.dll
、opencv_world411.dll
、opencv_videoio_ffmpeg411_64.dll
) Скопируйте файл в C:\Windows\System32
Просто скачайте его.
Linux Установить OpenCV Пожалуйста, перейдите по ссылке: Linux Настройка серверной среды
Добавьте библиотеку OpenCV в путь сборки вашего проекта Java и используйте класс VideoCapture, чтобы открыть камеру.
Добавить зависимости
<!--openCV Пакет зависимостей-->
<dependency>
<groupId>org.opencv</groupId>
<artifactId>opencv</artifactId>
<version>4.1.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/opencv-411.jar</systemPath>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork> <!-- Без этой настройки инструменты разработчика не вступят в силу. -->
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>
Примечание. Если fork и includeSystemScope не настроены, упаковка не вступит в силу.
открыть камеру
package com.demo.utils;
import lombok.extern.slf4j.Slf4j;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.videoio.VideoCapture;
import org.opencv.videoio.VideoWriter;
import static org.opencv.videoio.Videoio.CAP_PROP_FRAME_HEIGHT;
import static org.opencv.videoio.Videoio.CAP_PROP_FRAME_WIDTH;
@Slf4j
public class RtspRecordingUtil {
public static void main(String[] args) {
init();
}
public static void init() {
// Загрузить библиотеку
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
VideoCapture capture = new VideoCapture();
capture.open("rtsp://admin:123456@192.168.1.11/Streaming/Channels/101");
log.info("=======isOpen:{}========", capture.isOpened());
if (capture.isOpened()) {
Mat mat = new Mat();
VideoWriter vw = new VideoWriter();
Size size = new Size();
size.width = capture.get(CAP_PROP_FRAME_WIDTH);
size.height = capture.get(CAP_PROP_FRAME_HEIGHT);
boolean t = vw.open("F:\\test.avi", VideoWriter.fourcc('M', 'P', '4', '2'), 30, size);
// Записывать
while (capture.read(mat)) {
vw.write(mat);
}
capture.release();
vw.release();
}
log.info("========Конец======");
}
}
Приведенный выше пример кода сначала загружает библиотеку OpenCV и создает объект VideoCapture, чтобы открыть камеру по умолчанию. Затем используйте цикл для чтения каждого кадра изображения и записи его в VideoWriter для сохранения.
Открыть несколько камер
Чтобы открыть несколько камер, мы можем извлекать разные потоки видео, создавая несколько потоков.
package com.demo.util;
import lombok.extern.slf4j.Slf4j;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.videoio.VideoCapture;
import org.opencv.videoio.VideoWriter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.Duration;
import java.time.Instant;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static org.opencv.videoio.Videoio.CAP_PROP_FRAME_HEIGHT;
import static org.opencv.videoio.Videoio.CAP_PROP_FRAME_WIDTH;
@Slf4j
@Component
public class RtspRecordingUtil {
// видео Сохранить адрес
@Value("${video.video-path}")
private String videoPath;
// Запись видеоиз продолжительности по умолчанию
@Value("${video.video-recording-duration}")
private Long videoRecordingDuration;
// По умолчанию включены десять потоков.
private String DEFAULT_THREAD_POOL = 10;
ExecutorService executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL);
{
/**
* Воля Следующие три файла:
* opencv_java411.dll、
* opencv_world411.dll、
* opencv_videoio_ffmpeg411_64.dll
* Скопируйте файлы в C:\Windows\System32 в каталоге
*/
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
// Его можно запустить локально, но после упаковки файл найти невозможно.
/**
String path = this.getClass().getClassLoader().getResource("").getPath();
System.load(path + "lib/dll/opencv_java411.dll");
System.load(path + "lib/dll/opencv_world411.dll");
System.load(path + "lib/dll/opencv_videoio_ffmpeg411_64.dll");
*/
}
public String recording(String username, String password, String ip, Integer chanelId, String videoName, Integer duration) {
executorService.submit(new VideoCaptureTask(username, password, ip, chanelId, videoName, duration));
return "ok";
}
class VideoCaptureTask implements Runnable {
// Имя пользователя устройства
private String username;
// Пароль устройства
private String password;
// IP-адрес устройства
private String ip;
// Номер канала устройства
private Integer chanelId;
// видеоимя private String videoName;
// Записыватьпродолжительность
private Integer duration;
public VideoCaptureTask(String username, String password, String ip, Integer chanelId, String videoName, Integer duration) {
this.username = username;
this.password = password;
this.ip = ip;
this.chanelId = chanelId;
this.videoName = videoName;
this.duration = duration;
}
@Override
public void run() {
VideoCapture capture = null;
VideoWriter vw = null;
try {
capture = new VideoCapture(videoName);
String url = "rtsp://" + username + ":" + password + "@" + ip + "/Streaming/Channels/" + (Objects.nonNull(chanelId) ? chanelId : "1");
capture.open(url);
log.info("==== VideoCapture Начало... URL: {} ======= isOpened:{}=====", url, capture.isOpened());
if (capture.isOpened()) {
Mat mat = new Mat();
Size size = new Size(capture.get(CAP_PROP_FRAME_WIDTH), capture.get(CAP_PROP_FRAME_HEIGHT));
// адрес хранения видео
vw = new VideoWriter();
// Определите, содержит ли каталог хранения существующие
if (Files.notExists(Paths.get(videoPath))) {
Files.createDirectories(Paths.get(videoPath));
}
vw.open(videoPath + videoName + ".avi", VideoWriter.fourcc('M', 'P', '4', '2'), 30, size);
Instant start = Instant.now();
long seconds = 0;
long _duration = Objects.nonNull(duration) ? duration : videoRecordingDuration;
while (capture.read(mat) && seconds <= _duration) {
vw.write(mat);
seconds = Duration.between(start, Instant.now()).getSeconds();
}
}
log.info("==== VideoCapture Конец....URL: {} =====", url);
} catch (Exception e) {
log.error("==== VideoCapture аномальный:{}", e);
} finally {
if (Objects.nonNull(capture)) capture.release();
if (Objects.nonNull(vw)) vw.release();
}
}
}
}
Необходимо разобраться с несоответствием разрешения и частоты кадров между различными камерами, а также подумать о том, как эффективно управлять несколькими VideoCapture Пример проблемы,здесьиспользоватьвидеоимякак Камераизиндекс(new VideoCapture(videoName)
)Предотвращение дублирования экземпляров。