Посмотрите вводное видео в двух разделах выше, без кода.
В приведенных выше главах используется метод, не требующий установки, поэтому вы можете сразу пропустить главу об установке и сэкономить время на интеграцию OpenCV с Springboot (вы также можете использовать проект Maven или простой проект Java. Главное — ввести jar). Пакет и файл библиотеки. Банка является кроссплатформенной, а библиотека. Файл не является кроссплатформенным, поэтому вам придется различать Windows и Linux. Что касается идеи инструмента, то все в порядке.
Установка среды может относиться к:Springboot интегрирует Opencv без установки и совместим с Windows и Linux.
Фактический код
/**
* Прочитай картинку и покажи ее
*/
public class P1ReadAndDisplayImage {
public static void main(String[] args) {
// Загрузить библиотеку Opencv Он не обязательно должен быть в проекте, ему нужен абсолютный путь.
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// Читать картинки
Mat img = Imgcodecs.imread("src/main/resources/img/lenna1.png");
// Отображение изображений в окне приветствия
HighGui.imshow("hello", img);
// Подождите нажатия клавиши Если не настроить дизайн, он будет ждать вечно.
HighGui.waitKey();
// Уничтожить все окна
HighGui.destroyAllWindows();
// Выйти из системы
System.exit(0);
}
}
public class P2SaveImage {
public static void main(String[] args) {
// Загрузить библиотеку Opencv Он не обязательно должен быть в проекте, ему нужен абсолютный путь.
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// Читать картинки
Mat img = Imgcodecs.imread("src/main/resources/img/lenna1.png");
// сохранить изображение Формат изображения может совпадать с исходным изображением или быть несовместимым.
String fileName = "src/main/resources/tmp/lenna1.jpg";
Imgcodecs.imwrite(fileName, img);
}
}
public class P3CameraStudy {
public static void main(String[] args) {
// Загрузить динамическую библиотеку
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// Откройте камеру по умолчанию (индекс 0).
VideoCapture capture = new VideoCapture(0);
// Проверьте, успешно ли открылась Камера
if (!capture.isOpened()) {
System.out.println("Невозможно открыть камеру.");
return;
}
// Чтение и отображение каждого кадра из камеры.
Mat frame = new Mat();
while (capture.read(frame)) {
// Показать изображение Связанный с пользовательским интерфейсом HighGui
HighGui.imshow("Camera", frame);
// подожди 3 миллисекунды То есть один кадр считывается из Камеры каждые 3 миллисекунды.
int key = HighGui.waitKey(3);
// Если вы введете q затем освободите ресурсы
if (key == 'q' || key == 'Q') {
// Уничтожить все окна
HighGui.destroyAllWindows();
// выпускать VideoCapture объект
capture.release();
System.exit(0);
break;
}
}
// Уничтожить все окна
HighGui.destroyAllWindows();
// выпускать VideoCapture объект
capture.release();
System.exit(0);
}
}
public class P4VideoStudy {
public static void main(String[] args) {
// Загрузить динамическую библиотеку
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// Читать местные видео
VideoCapture capture = new VideoCapture("src/main/resources/video/video.mp4");
// Получите ширину, высоту и количество кадров видео.
double width = capture.get(Videoio.CAP_PROP_FRAME_WIDTH);
double height = capture.get(Videoio.CAP_PROP_FRAME_HEIGHT);
double frameCount = capture.get(Videoio.CAP_PROP_FRAME_COUNT);
// Получите номер кадра и общую продолжительность видео
double totalSeconds = frameCount / capture.get(Videoio.CAP_PROP_FPS);
// Рассчитать среднюю частоту кадров
double fps = frameCount / totalSeconds;
// Вывод видеоинформации
System.out.println("Ширина видео: " + width);
System.out.println("видео Высота: " + height);
System.out.println("Номер видеокадра: " + frameCount);
System.out.println("Общая продолжительность: " + totalSeconds);
System.out.println("Средняя частота кадров: " + fps);
// Определить путь к выходному видеофайлу
String outputFilePath = "src/main/resources/tmp/output_video.mp4";
// Определите атрибут видео width и height Неправильно, я не могу это написать
Size frameSize = new Size(width, height);
// создавать VideoWriter объект
VideoWriter videoWriter = new VideoWriter(outputFilePath, VideoWriter.fourcc('H', '2', '6', '4'), fps, frameSize, true);
// Проверьте, успешно ли открылось видео
if (!capture.isOpened()) {
System.out.println("Невозможно открыть видео");
return;
}
// исследовать VideoWriter объект успешно инициализирован?
if (!videoWriter.isOpened()) {
System.out.println("Ошибка: невозможно открыть файл видео для записи.");
return;
}
// Чтение и отображение каждого кадра из видео
Mat frame = new Mat();
while (capture.read(frame)) {
if (!frame.empty()) {
videoWriter.write(frame);
}
// Показать изображение Связанный с пользовательским интерфейсом HighGui
HighGui.imshow("Video", frame);
// Оно прерывается после одного ввода.
int key = HighGui.waitKey(30);
System.out.println("key = " + key+"\t" + (char)key);
if (key == 'q' || key == 'Q') {
HighGui.destroyAllWindows();
capture.release();
videoWriter.release();
System.exit(0);
break;
}
}
HighGui.destroyAllWindows();
capture.release();
videoWriter.release();
System.exit(0);
}
}
Я считаю, что нет необходимости читать приведенные выше главы, поэтому вы можете их просто игнорировать.
Чистая теория, вы можете посмотреть видео напрямую
Не обращайте внимания на три вышеуказанных раздела, Java предоставляет API ROI (область интереса ROI — это часть изображения, которая вас больше беспокоит)
Вставьте класс инструментов для отображения изображений, чтобы решить проблему совместного отображения изображений и расположения изображений с эффектами на экране.
public static void show(LinkedHashMap<String, Mat> mats) {
// Получите набор инструментов по умолчанию
Toolkit toolkit = Toolkit.getDefaultToolkit();
// Узнать размер экрана
Dimension screenSize = toolkit.getScreenSize();
// Ширина и высота выходного экрана
int i = 0;
int x = 0;
int y = 0;
int xSpacing = 10;
int ySpacing = 40;
for (Map.Entry<String, Mat> entry : mats.entrySet()) {
Mat mat = entry.getValue();
String winName = entry.getKey();
System.out.println("winName = " + winName);
HighGui.imshow(winName, mat);
if (i > 0) {
x += (mat.cols() + xSpacing);
if (x + mat.cols() > screenSize.width) {
x = 0;
y += (mat.rows() + ySpacing);
}
}
HighGui.moveWindow(winName, x, y);
i++;
}
HighGui.waitKey();
}
public class P490MatCopyStudy {
public static void main(String[] args) {
// Загрузить динамическую библиотеку
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// Читать картинки
Mat image = Imgcodecs.imread("src/main/resources/img/lenna1.png");
// это глубокая копия
Mat clone = image.clone();
// глубокая копия
Mat copyTo = new Mat();
image.copyTo(copyTo);
// Нарисовать текст на изображении
// позиция текста
Point textPosition = new Point(50, 50);
String text = "Hello, OpenCV!";
// Белый, размер шрифта 1.0, ширина линии равна 2
Imgproc.putText(image, text, textPosition, Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 255), 2);
LinkedHashMap<String, Mat> images = new LinkedHashMap<>();
images.put("исходное изображение", image);
images.put("clone", clone);
images.put("copyTo", copyTo);
OpenCVUtil.show(images);
HighGui.destroyAllWindows();
}
}
Примечание. Как видно из приведенного выше кода, clone и copyTo являются глубокими копиями в Java.
public class P412MatSplitAndMerge {
public static void main(String[] args) {
// Загрузить динамическую библиотеку
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// Прочитайте исходное изображение
Mat image = Imgcodecs.imread("src/main/resources/img/lenna1.png");
// Показать изображение
HighGui.imshow("исходное изображение", image);
// разделительный канал
List<Mat> channels = new ArrayList<>();
Core.split(image, channels);
for (int i = 0; i < channels.size(); i++) {
Mat mat = channels.get(i);
// Все три отдельных канала представляют собой одиночные каналы, поэтому все они представляют собой черно-белые изображения.
HighGui.imshow("Канал" + i, mat);
}
List<Mat> mergeChannels = new ArrayList<>();
mergeChannels.add(channels.get(0));
mergeChannels.add(channels.get(1));
mergeChannels.add(channels.get(2));
Mat newMat = new Mat();
// Объединить каналы
Core.merge(mergeChannels,newMat);
HighGui.imshow("Комбинированное изображение", newMat);
HighGui.waitKey();
HighGui.destroyAllWindows();
System.exit(0);
}
}
Кодекс практики
public class P500BasicShapeDrawingExample {
public static void main(String[] args) {
// Загрузить динамическую библиотеку
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// Создатель изображения на черном фоне
Mat image = new Mat(400, 600, CvType.CV_8UC3, new Scalar(0, 0, 0)); // 400x600 размер, 3 черное изображение канала
// На изображении Рисовать базовую графику
Point center = new Point(300, 200); // Координаты центра круга
Scalar color = new Scalar(0, 255, 0); // цвет (BGR Формат)
// Нарисуйте круг
Imgproc.circle(image, center, 100, color, 2); // Центр (300, 200), радиус 100, ширина границы 2, зеленый
// Нарисуйте прямоугольник
Point topLeft = new Point(100, 100); // Координаты верхнего левого угла
Point bottomRight = new Point(500, 300); // Координаты нижнего правого угла
Imgproc.rectangle(image, topLeft, bottomRight, new Scalar(0, 0, 255), 3); // верхний левый угол (100, 100), нижний правый угол (500, 300), красный, ширина границы равна 3
// Нарисуйте прямую линию
Point start = new Point(50, 50); // Координаты начальной точки
Point end = new Point(550, 350); // Координаты конечной точки
Imgproc.line(image, start, end, new Scalar(255, 0, 0), 1); // Синий, ширина линии 1
// Нарисовать текст на изображении
Point textPosition = new Point(50, 50); // позиция текста
String text = "Hello, OpenCV!"; // текст для рисования
Imgproc.putText(image, text, textPosition, Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 255), 2); // Белый, размер шрифта 1.0, ширина линии равна 2
HighGui.imshow("Отрисовка базовой графики", image);
HighGui.waitKey(0);
HighGui.destroyAllWindows();
System.exit(0);
}
}
Эффект
public class P620ImageArithmeticExample {
public static void main(String[] args) {
// // Загрузить динамическую библиотеку
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// Загрузите два изображения
String imagePath1 = "src/main/resources/img/lenna1.png";
Mat image1 = Imgcodecs.imread(imagePath1);
// Загружено ли изображение успешно?
if (image1.empty()) {
System.out.println("Error: Couldn't load images.");
return;
}
HighGui.imshow("исходное изображение", image1);
// создать Изображение 2 тех же размеров, что и изображение 1.,Каждый пиксель имеет значение 100.
Mat image2 = new Mat(image1.size(), image1.type(), new Scalar(100));
// создавать一个с изображениями1размери Пустое изображение того же типа,используется для хранения результатов
Mat result4add = new Mat(image1.size(), image1.type());
Mat result4subtract = new Mat(image1.size(), image1.type());
// Добавление
Core.add(image1, image2, result4add);
HighGui.imshow("Добавить изображения", result4add);
// операция вычитания
Core.subtract(image1, image2, result4subtract);
HighGui.imshow("Вычитание изображения", result4subtract);
HighGui.waitKey(0);
HighGui.destroyAllWindows();
System.exit(0);
}
}
Изменение светотени изображения (смешанные операции сложения, вычитания, умножения и деления изображения)
public class P621DarknessAdjustmentExample {
public static void main(String[] args) {
// Загрузить динамическую библиотеку
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// Загрузите два изображения
Mat image1 = Imgcodecs.imread("src/main/resources/img/lenna1.png");
// Загружено ли изображение успешно?
if (image1.empty()) {
System.out.println("Error: Couldn't load images.");
return;
}
HighGui.imshow("исходное изображение", image1);
// Определяет коэффициент регулировки темноты (в 0 приезжать 1 между)
double darknessFactor = 0.5; // уменьшать 50%
// Умножьте значение каждого пикселя изображения 1 на коэффициент регулировки темноты.
// rtype: преобразованный целевой тип данных. Если значение -1 означает использование того же источника Mat объект того же типа данных.
// Исходное значение пикселя*альфа+бета
Mat clone = image1.clone();
clone.convertTo(clone, -1, darknessFactor, 0);
HighGui.imshow("После смены света и тьмы", clone);
HighGui.waitKey(0);
HighGui.destroyAllWindows();
System.exit(0);
}
}
public class P630ImageFusionExample {
public static void main(String[] args) {
// Загрузить динамическую библиотеку
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// прочитать изображение1иизображение2
Mat image1 = Imgcodecs.imread("src/main/resources/img/dog.jpg");
Mat image2 = Imgcodecs.imread("src/main/resources/img/background.jpg");
// Fusion требует, чтобы оба изображения были одинакового размера.
Size size = getSize(image1, image2);
// слияние изображений
Mat blendedImage = blendImages(resizeImages(image1, size), resizeImages(image2, size));
// Отображение объединенного изображения
HighGui.imshow("Blended Image", blendedImage);
HighGui.waitKey(0);
HighGui.destroyAllWindows();
System.exit(0);
}
private static Size getSize(Mat image1, Mat image2) {
int minWidth = Math.min(image1.width(), image2.width());
int minHeight = Math.min(image1.height(), image2.height());
return new Size(minWidth, minHeight);
}
// Изменить размер изображения до нужного размера
private static Mat resizeImages(Mat image, Size size) {
Mat mat = new Mat(size, image.type());
Imgproc.resize(image, mat, size);
return mat;
}
// слияние изображений
private static Mat blendImages(Mat image1, Mat image2) {
double alpha = 0.9; // Отрегулируйте вес сплава
Mat blendedImage = new Mat();
Core.addWeighted(image1, alpha, image2, 1 - alpha, 0, blendedImage);
return blendedImage;
}
}
Исходное изображение 1
Слияние Эффект
public class P640ImageNegationExample {
public static void main(String[] args) {
// Загрузить динамическую библиотеку
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// прочитать изображение
Mat image = Imgcodecs.imread("src/main/resources/img/lenna1.png");
HighGui.imshow("исходное изображение", image);
Mat mat = new Mat();
Core.bitwise_not(image, mat);
// Отображение объединенного изображения
HighGui.imshow("НЕ работа с изображением", mat);
HighGui.waitKey(0);
HighGui.destroyAllWindows();
System.exit(0);
}
}
public class P670AddLogo {
public static void main(String[] args) {
// Загрузить динамическую библиотеку
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// 1. Представьте изображения
Mat background = Imgcodecs.imread("src/main/resources/img/background.jpg");
// 2. Сделать логотип
Mat logo = new Mat(200, 200, CvType.CV_8UC3, new Scalar(0, 0, 0));
Mat mask = new Mat(200, 200, CvType.CV_8UC1, new Scalar(0, 0, 0));
Point topLeft = new Point(20, 20);
Point bottomRight = new Point(120, 120);
Imgproc.rectangle(logo, topLeft, bottomRight, new Scalar(0, 0, 255), 2);
Imgproc.rectangle(mask, topLeft, bottomRight, new Scalar(255, 255, 255), 2);
topLeft = new Point(80, 80);
bottomRight = new Point(180, 180);
Imgproc.rectangle(logo, topLeft, bottomRight, new Scalar(0, 255, 0), 2);
Imgproc.rectangle(mask, topLeft, bottomRight, new Scalar(255, 255, 255), 2);
Mat m = new Mat();
Core.bitwise_not(mask, m);
HighGui.imshow("logo", logo);
HighGui.imshow("mask", mask);
HighGui.imshow("m", m);
// 3. Вычислить добавленную позицию и затемнить добавленную позицию
Mat roi = new Mat(background, new Rect(0, 0, 200, 200));
HighGui.imshow("roi", roi);
Mat tmp = new Mat();
Core.bitwise_and(roi, roi, tmp, m);
HighGui.imshow("tmp", tmp);
Mat dst = new Mat();
Core.add(tmp, logo, dst);
HighGui.imshow("dst",летнее время);
// 4.Используйте добавление,Наложение картинки и логотипа с надписью приезжать
Mat submat = background.submat(new Rect(0, 0, 200, 200));
dst.copyTo(submat);
HighGui.imshow("background", background);
HighGui.waitKey(0);
HighGui.destroyAllWindows();
System.exit(0);
}
}
public class P710Scale {
public static void main(String[] args) {
// Загрузить динамическую библиотеку
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// прочитать изображение
Mat originalImage = Imgcodecs.imread("src/main/resources/img/idea.png");
// Определите размер изображения после масштабирования
Size newSize = new Size(originalImage.width() * 5, originalImage.height() * 5);
// Масштабировать изображение (с использованием бикубической интерполяции)
Mat resizedImage = new Mat();
Imgproc.resize(originalImage, resizedImage, newSize, 0, 0, Imgproc.INTER_AREA);
// 显示原始изображениеи缩放后的изображение
HighGui.imshow("Original Image", originalImage);
HighGui.imshow("Resized Image", resizedImage);
HighGui.waitKey(0);
HighGui.destroyAllWindows();
System.exit(0);
}
}
Примечание. Первое изображение — это исходное изображение, а второе — изображение, увеличенное в 5 раз. После увеличения изображение будет размытым.
/**
* инверсия изображения
* 0: переворот по оси X (переворот по вертикали).
* 1: Перевернуть по оси Y (перевернуть по горизонтали)
* -1: одновременное переворот по осям X и Y.
*/
public class P730ImageFlipExample {
public static void main(String[] args) {
// Загрузить динамическую библиотеку
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// прочитать изображение
Mat originalImage = Imgcodecs.imread("src/main/resources/img/lenna1.png");
// Отразить по оси X (отразить по вертикали)
Mat dstX = new Mat();
Core.flip(originalImage, dstX, 0);
// Отразить по оси Y (отразить по горизонтали)
Mat dstY = new Mat();
Core.flip(originalImage, dstY, 1);
Mat dstXY = new Mat();
Core.flip(originalImage, dstXY, -1);
LinkedHashMap<String, Mat> images = new LinkedHashMap<>();
images.put("исходное изображение", originalImage);
images.put("Перевернуть по оси X", dstX);
images.put("Перевернуть по оси Y", dstY);
images.put("Одновременно перевернуть по оси XY", dstXY);
OpenCVUtil.show(images);
HighGui.destroyAllWindows();
System.exit(0);
}
}
Эффекткартина
/**
* Аффинное преобразование
*/
public class P760ImageRotateExample {
public static void main(String[] args) {
// Загрузить динамическую библиотеку
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// прочитать изображение
Mat originalImage = Imgcodecs.imread("src/main/resources/img/lenna1.png");
// Определить угол поворота (против часовой стрелки)
double angle = 45.0;
// Получить центральную точку изображения
Point center = new Point(originalImage.cols() / 2, originalImage.rows() / 2);
// Вычислить матрицу вращения
Mat rotationMatrix = Imgproc.getRotationMatrix2D(center, angle, 1.0);
// Выполнить преобразование вращения
Mat rotatedImage = new Mat();
Imgproc.warpAffine(originalImage, rotatedImage, rotationMatrix, new Size(originalImage.cols(), originalImage.rows()));
// 显示原始изображениеи旋转后的изображение
LinkedHashMap<String, Mat> images = new LinkedHashMap<>();
images.put("исходное изображение", originalImage);
images.put("Повернуть на 45° против часовой стрелки", rotatedImage);
OpenCVUtil.show(images);
HighGui.destroyAllWindows();
System.exit(0);
}
}
OpenCV предоставляет множество различных типов фильтров, которые можно использовать для различных задач обработки изображений. Вот некоторые часто используемые типы фильтров:
- Средний фильтр (Среднее Filter):用于平滑изображение并уменьшатьшум。Он вычисляет среднее значение площади, окружающей пиксель.,и замените значение центрального пикселя на это среднее значение。
- Фильтр Гаусса (Гауссов фильтр Filter):也用于平滑изображение并уменьшатьшум,Но по сравнению со средним фильтром,Это более гладко. Он вычисляет средневзвешенное значение области, окружающей пиксель.,Веса определяются функциями Гаусса。
- Медианный фильтр (Медиана Фильтр): используется для удаления спекл-шума, такого как шум соли и перца. Он сортирует значения области вокруг пикселя и заменяет значение центрального пикселя медианным значением.
- Двусторонний фильтр Filter):用于平滑изображение并保持边缘清晰。Учитывает пространственное расстояние между пикселямии Сходство между значениями пикселей,для определения весов фильтров. Фильтрация верхних частот: обнаружение краев
- Фильтр Собеля: используется для обнаружения границ. Он использует два ядра свертки 3х3.,分别计算изображение的水平ивертикальный градиент。
- Фильтр Лапласа: также используется для обнаружения краев. Он вычисляет вторую производную изображения и может извлекать края изображения.