目录

简介

Maven

软件环境

JavaCV-Examples

OpenCV Cookbook Examples

概述

示例

OpenCV文档

如何使用JavaCV示例

示例代码的组织结构

示例列表

Why Scala?

学习地址

图像简单处理代码示例

1.打开保存一张图

2.画直线

3.画圆圈

4.画折现

5.添加文字水印

6.裁剪并局部放大

7.人脸检测

视频简单处理代码示例

1.打开视频文件

2.抓取视频指定时间的帧保存为图像

3.录屏

4.给视频添加水印


简介

JavaCV使用来自JavaCPP预设库的包装器,这些库是计算机视觉领域的研究人员常用的库(OpenCV, FFmpeg, libdc1394, FlyCapture, Spinnaker, OpenKinect, librealsense, CL PS3 Eye Driver, videoInput, ARToolKitPlus, flandmark, Leptonica和Tesseract),并提供实用程序类,使其功能更容易在Java平台(包括Android)上使用。

JavaCV还具有硬件加速全屏图像显示(CanvasFrame和GLCanvasFrame),易于使用的方法在多核上并行执行代码(parallel),用户友好的相机和投影仪的几何和颜色校准(GeometricCalibrator, ProCamGeometricCalibrator, ProCamColorCalibrator),特征点的检测和匹配(ObjectFinder),一组实现投影仪-相机系统的直接图像对齐的类(主要是GNImageAligner,projectvetransformer, projvecolortransformer, ProCamTransformer和ReflectanceInitializer),一个blob分析包(Blobs),以及JavaCV类中的其他功能。其中一些类也有OpenCL和OpenGL对应的类,它们的名字以CL结尾或以GL开头,例如:JavaCVCL, GLCanvasFrame等。

要学习如何使用API,因为目前缺乏文档,请参考下面的示例用法部分以及示例程序,包括两个Android (FacePreview.java和RecordActivity.java),也可以在samples目录中找到。您还可以参考ProCamCalib和ProCamTracker的源代码,以及从OpenCV2 Cookbook和相关wiki页面移植的示例。

Maven

  <dependency><groupId>org.bytedeco</groupId><artifactId>javacv-platform</artifactId><version>1.5.8</version></dependency>

软件环境

要使用JavaCV,首先需要下载并安装以下软件:

Java SE 7或更新版本的实现:

  • OpenJDK OpenJDK: Download and install or

  • Oracle JDK http://www.oracle.com/technetwork/java/javase/downloads/ or

  • IBM JDK http://www.ibm.com/developerworks/java/jdk/

此外,虽然并不总是必需的,JavaCV的一些功能也依赖于:

  • CL Eye Platform SDK (Windows only) CL - Downloads - Code Laboratories

    CL Eye平台SDK为开发人员提供了对相机使用和操作的完全访问和控制。为了可移植性和易用性,所提供的api作为标准的基于C的函数公开,还包括作为基线测试框架的所有示例应用程序的完整源代码。

  • Android SDK API 21 or newer http://developer.android.com/sdk/

  • JOCL and JOGL from JogAmp JogAmp.org - Java graphics, audio, media and processing libraries exposing OpenGL, OpenCL, OpenAL and OpenMAX

    JogAmp是用于3D图形、多媒体和处理的高性能Java™库的家。

    JOGL, JOCL和JOAL提供跨平台Java™语言绑定到OpenGL®,OpenCL™,OpenAL和OpenMAX api。

最后,请确保所有内容具有相同的位,32位和64位模块在任何情况下都不能混合。

JavaCV-Examples

这个项目包含使用JavaCV和其他javacpp-presets项目中的库包装器的示例。

  • OpenCV_Cookbook - Robert laganiere的书《OpenCV Computer Vision Application Programming Cookbook》中提供的示例的JavaCV版本。Cookbook中的原始示例是用c++编写的,这里它们被翻译为使用JavaCV API。

  • 使用flandmark库的示例。

  • 使用JVM包装flr /Point Grey FlyCapture SDK的示例。

  • 使用JVM包装Flir/Point Grey Spinnaker SDK的示例

OpenCV Cookbook Examples

概述

OpenCV Cookbook示例说明了OpenCV与JavaCV的使用。这些例子是从Robert laganie:1的书《OpenCV 2计算机视觉应用程序编程指南》中移植的c++代码开始的。后来更新为第四版的书“OpenCV计算机视觉应用程序编程 Cookbook第四版”。书中的示例使用OpenCV c++ API。在这里,它们被转换为使用JavaCV和JavaCPP-Presets api。

OpenCV(开源计算机视觉)是一个包含数百种算法的库,用于计算机视觉和视频分析。OpenCV可以通过两种方式在JVM上运行。首先是由OpenCV提供的Java包装器。第二种是基于JavaCPP (JVM的c++包装器引擎)的包装器,称为OpenCV JavaCPP预置。还有其他计算机视觉相关库的JavaCPP预设,如:FFmpeg, libdc1394, PGR FlyCapture, OpenKinect, videoInput, ARToolKitPlus, landmark等。JavaCV结合了JavaCPP预置中的库,并添加了一些额外的功能,使它们更容易在JVM上使用。

OpenCV Cookbook Examples项目演示了通过JavaCV和OpenCV JavaCPP预设使用OpenCV。当前的版本更新是为了匹配Robert laganie:1的书“OpenCV计算机视觉应用程序编程 Cookbook第二版”的第二版。它旨在与OpenCV .4一起使用(JavaCV 1节)。

虽然示例中的代码主要是用Scala编写的,Scala是领先的JVM语言之一。它可以很容易地转换为Java和运行在JVM上的其他语言,例如Groovy。在大多数JVM语言中,JavaCV API的使用非常相似。在Java版本中提供了一些示例。

示例

下面是一个快速预览,将原始c++示例与使用JavaCV包装器的Scala和Java代码进行比较。

下面是一个原始的c++示例,它打开一个图像(没有错误检查),创建一个窗口,在窗口中显示图像,并等待5秒后退出。

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgcodecs/imgcodecs.hpp>int main() {// Read an imagecv::Mat src = cv::imread("data/boldt.jpg");display(src, "Input")// Apply Laplacian filtercv::Mat dest;cv::Laplacian(src, dest, src.depth(), 1, 3, 0, BORDER_DEFAULT);display(dest, "Laplacian");// wait key for 5000 mscv::waitKey(5000);return 1;
}//---------------------------------------------------------------------------void display(Mat image, char* caption) {// Create image window named "My Image"cv::namedWindow(caption);// Show image on windowcv::imshow(caption, image);
}

上面的c++示例使用JavaCV包装器转换为Scala:

import javax.swing._
import org.bytedeco.javacv._
import org.bytedeco.opencv.global.opencv_core._
import org.bytedeco.opencv.global.opencv_imgcodecs._
import org.bytedeco.opencv.global.opencv_imgproc._
import org.bytedeco.opencv.opencv_core._object MyFirstOpenCVApp extends App {// Read an image.val src = imread("data/boldt.jpg")display(src, "Input")// Apply Laplacian filterval dest = new Mat()Laplacian(src, dest, src.depth(), 1, 3, 0, BORDER_DEFAULT)display(dest, "Laplacian")//---------------------------------------------------------------------------/** Display `image` with given `caption`. */def display(image: Mat, caption: String): Unit = {// Create image window named "My Image."val canvas = new CanvasFrame(caption, 1)// Request closing of the application when the image window is closed.canvas.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)// Convert from OpenCV Mat to Java Buffered image for displayval converter = new OpenCVFrameConverter.ToMat()// Show image on windowcanvas.showImage(converter.convert(image))}
}

现在用Java表达相同的例子。请注意,JavaCV API的使用与Scala和Java代码中的完全相同。唯一的实际区别是,在Java代码中更冗长,您必须显式地为每个变量提供类型,而在Scala中这是可选的。

import org.bytedeco.javacv.CanvasFrame;
import org.bytedeco.opencv.opencv_core.Mat;import javax.swing.*;
import java.awt.image.BufferedImage;import static opencv_cookbook.OpenCVUtilsJava.toBufferedImage;
import static org.bytedeco.opencv.global.opencv_core.BORDER_DEFAULT;
import static org.bytedeco.opencv.global.opencv_imgcodecs.imread;
import static org.bytedeco.opencv.global.opencv_imgproc.Laplacian;public class MyFirstOpenCVAppInJava {public static void main(String[] args) {// Read an image.final Mat src = imread("data/boldt.jpg");display(src, "Input");// Apply Laplacian filterfinal Mat dest = new Mat();Laplacian(src, dest, src.depth(), 1, 3, 0, BORDER_DEFAULT);display(dest, "Laplacian");}//---------------------------------------------------------------------------static void display(Mat image, String caption) {// Create image window named "My Image".final CanvasFrame canvas = new CanvasFrame(caption, 1.0);// Request closing of the application when the image window is closed.canvas.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);// Convert from OpenCV Mat to Java Buffered image for displayfinal BufferedImage bi = toBufferedImage(image);// Show image on window.canvas.showImage(bi);}
}

OpenCV文档

如果您正在寻找一个特定的OpenCV操作,请使用OpenCV文档(OpenCV documentation index)。快速搜索框特别有用。该文档包含了C/ c++ OpenCV API可选使用方式的描述。

如何使用JavaCV示例

OpenCV Cookbook示例项目是作为Robert laganie:1的书“OpenCV计算机视觉应用程序编程Cookbook第二版”的伙伴。推荐的方法是在对如何将Cookbook的c++代码转换为JavaCV有疑问时阅读Cookbook并参考JavaCV示例。这本书解释了算法是如何工作的。JavaCV示例只提供了与JavaCV API细节相关的非常简短的注释。

使用JavaCV示例的最简单方法是在线浏览位于[src/main]中的代码。您也可以使用Git或ZIP文件将其下载到计算机上。

通过最小的设置,您可以轻松地在自己的计算机上执行示例。这是JavaCV的好处之一——它提供了在各种平台上运行OpenCV所需的所有二进制文件。在第1章的README中解释了这个设置。

示例代码的组织结构

代码被组织成与Cookbook第1版中的章节相对应的包,例如opencv_cookbook.chapter8。它与第二版非常相似。个别的例子大致对应于书中每一章的章节。

第1章描述了运行这些示例的IDE设置,给出了一个加载和显示图像的基本示例,以及一个执行基本图像处理的基本GUI示例。

示例列表

第一章:使用图像

  • Ex1MyFirstOpenCVApp -加载图像并在窗口中显示它(CanvasFrame)

  • Ex2MyFirstGUIFXApp -使用ScalaFX (JavaFX包装器)构建的简单GUI应用程序。该应用程序在左侧有两个按钮“打开图像”和“处理”。打开的图像显示在中间。当按下“处理”按钮时,图像被翻转过来,其红色和蓝色通道被交换。有关Swing版本,请参阅Ex2MyFirstGUIApp。

  • Ex2MyFirstGUIApp -使用Scala Swing构建的简单GUI应用程序。该应用程序在左侧有两个按钮“打开图像”和“处理”。打开的图像显示在中间。当按下“处理”按钮时,图像被翻转过来,其红色和蓝色通道被交换。有关JavaFX版本,请参阅Ex2MyFirstGUIFXApp。

  • Ex3LoadAndSave -读取,保存,显示和绘制图像。

第二章:操纵像素

  • Ex1Salt -设置个人,随机选择,像素到一个固定的值。使用ImageJ的ImageProcessor来访问像素。

  • Ex2ColorReduce -通过相同的方式修改所有波段的颜色值来减少图像中的颜色。

  • ex3锐化-使用内核卷积锐化图像:filter2D()。

  • Ex4BlendImages -混合两个图像使用加权加法:cvAddWeighted()。

  • ex5roillogo -使用感兴趣的区域将小图像粘贴到较大的图像中:IplROI和cvCopy()。

第三章:用类处理图像

  • Ex1ColorDetector -将RGB颜色与目标颜色进行比较,与目标颜色相似的颜色在输出图像中被分配为白色,其他像素被设置为黑色。

  • Ex2ColorDetectorSimpleApplication—第一个示例的处理过程相同,但演示了一个简单的UI。

  • ex3colordetectormvapplication—相同的处理是第一个示例,但演示了一个更详细的UI。

  • Ex4ConvertingColorSpaces -类似于第一个例子,但是颜色距离是在Lab*颜色空间中计算的。说明cvtColor函数的使用。

第四章:用直方图计算像素

  • Ex1ComputeHistogram -使用实用程序类Histogram1D计算直方图,并将值打印到屏幕上。

  • Ex2ComputeHistogramGraph -显示使用实用程序类Histogram1D创建的直方图的图形。

  • Ex3Threshold -使用OpenCV threshold()方法将图像中的像素分离为前景和背景。

  • Ex4InvertLut—通过反转其查找表来创建倒立的图像。

  • Ex5EqualizeHistogram -使用直方图均衡化增强图像。

  • Ex6ContentDetectionGrayscale -使用灰度图像中区域的直方图来创建“模板”,通过整个图像来检测与该模板相似的像素。举例说明cvCalcBackProject()方法的使用。

  • Ex7ContentDetectionColor -使用区域直方图在彩色图像中创建“模板”,通过整个图像来检测与该模板相似的像素。依赖于工具类ColorHistogram和ContentFinder。

  • Ex8MeanShiftDetector -使用彩色图像中的区域直方图来创建“模板”,使用mean shift算法在另一张图像中找到“模板”的最佳匹配位置。举例说明cvMeanShift()方法的用法。

  • 使用辅助类ImageComparator计算图像相似度度量。

  • 执行直方图和查找表操作的Helper类,对应于OpenCV Cookbook中部分c++类Histogram1D的样例代码。举例说明OpenCV方法的使用:cvLUT(), cvEqualizeHist(), cvCreateHist(), cvCalcHist(), cvQueryHistValue_1D(), cvReleaseHist()。

  • ColorHistogram -帮助类简化了彩色图像cvCalcHist()方法的使用。

  • 使用cvCalcBackProject()方法进行模板匹配的辅助类。

  • ImageComparator -使用cvCompareHist()计算图像相似度的辅助类。

第五章:用形态学操作变换图像

  • 侵蚀和扩张-形态侵蚀和扩张:cvErode()和cvDilate()。

  • Ex2OpeningAndClosing -形态学打开和关闭:cvMorphologyEx()。

  • Ex3EdgesAndCorners -使用形态学过滤器检测边缘和角落。

  • Ex4WatershedSegmentation -图像分割使用分水岭算法。

  • Ex5GrabCut -使用grabCut()从背景中分离对象。

  • MorphoFeatures -等价于同名的c++类,包含形态学角检测的方法。

  • WatershedSegmenter -“使用分水岭分割图像”一节的辅助类。

第六章:过滤图像

  • Ex1LowPassFilter -模糊与高斯滤波器。

  • Ex2MedianFilter -用中值滤波器去除噪声。

  • Ex3DirectionalFilters -使用Sobel边缘检测滤波器。

  • 使用拉普拉斯滤波器的边缘检测。

  • LaplacianZC -计算Laplacian和过零,用于Ex4Laplacian。

第七章:提取线条、轮廓和组件

  • Ex1CannyOperator -检测轮廓与Canny算子。

  • Ex2HoughLines -使用标准Hough变换方法检测线条。

  • Ex3HoughLineSegments -使用概率霍夫变换方法检测线段。

  • Ex4HoughCircles -使用霍夫变换方法检测圆。

  • Ex5ExtractContours -使用连接的组件从二值图像中提取轮廓。

  • Ex6ShapeDescriptors -计算各种形状描述符:边界框,封闭圆,近似多边形,凸壳,质心。

  • LineFinder -使用概率霍夫变换方法检测线段的辅助类,用于Ex3HoughLineSegments。

第八章:发现兴趣点

  • Ex1HarrisCornerMap -计算哈里斯角强度图像。

  • Ex2HarrisCornerDetector -使用Harris角强度图像来检测定位良好的角,用一个角取代几个位置较近的检测(模糊)。使用HarrisDetector辅助类。

  • Ex3GoodFeaturesToTrack -使用GoodFeatures跟踪检测器的例子。

  • Ex4FAST -使用FAST检测器的示例。

  • Ex5SURF -使用SURF检测器的示例。

  • Ex6SIFT -使用SIFT检测器的示例。

  • 帮助类,用于哈里斯角强度图像的检测和定位。距离较近的探测(模糊)被单个探测取代。

第九章:发现兴趣点

  • Ex2TemplateMatching -从第一个图像(模板)和第二个图像中找到一个小补丁之间的最佳匹配。

  • ex7descripbingsurf -计算SURF特征,提取它们的描述符,并在同一物体的两幅图像之间找到最佳匹配的描述符。

第十章:估计图像中的投影关系

  • Ex1FindChessboardCorners -演示了相机校准步骤之一,在校准板中检测棋盘模式。

  • Ex2CalibrateCamera -相机校准示例,展示了如何校正光学器件可能引入的几何变形。使用CameraCalibrator助手类。

  • Ex3ComputeFundamentalMatrix -使用两幅图像之间检测和匹配的特征,计算描述两幅图像之间投影关系的基本矩阵。

  • Ex4MatchingUsingSampleConsensus -说明RANSAC(随机抽样共识)策略的使用。大多数计算是由RobustMatcher helper类完成的。

  • Ex5Homography -描述两个图像中点之间关系的另一种方法,使用homography。展示了如何将一个对象的部分视图的两个图像拼接在一起的示例。大多数计算是由RobustMatcher helper类完成的。

  • 实现摄像机校准算法的助手类。

  • RobustMatcher -实现基于RANSAC的算法,例如Ex4MatchingUsingSampleConsensus和Ex5Homography。

第十一章:处理视频序列

  • Ex1ReadVideoSequence -读取并显示视频。

  • Ex2ProcessVideoFrames -使用Canny边缘检测器处理视频文件中的帧;在屏幕上显示输出视频。使用辅助类VideoProcessor。

  • Ex3WriteVideoSequence -使用Canny边缘检测器处理视频文件中的帧;将输出写入视频文件。使用辅助类VideoProcessor。

  • Ex4TrackingFeatures -跟踪视频中的移动对象,标记屏幕上显示的视频中的跟踪点。大部分的实现是在FeatureTracker helper类中完成的。

  • Ex5ForegroundSegmenter -通过背景估计检测视频中的移动对象。背景使用“简单”移动平均方法建模,实现在助手类“BGFBSegmenter”中。

  • Ex6MOGMotionDetector -一个更复杂的运动检测器,使用混合高斯方法建模背景。

  • BGFBSEgmenter -通过使用移动平均线对背景建模,将“静态”背景与“移动”前景分开。使用的例子'Ex5ForegroundSegmenter'。

  • FeatureTracker -使用光流算法跟踪移动特征,例如Ex4TrackingFeatures。

  • VideoProcessor -处理视频文件的辅助类,加载和应用处理到单独的帧,例如:Ex2ProcessVideoFrames, Ex3WriteVideoSequence, Ex4TrackingFeatures和Ex5ForegroundSegmenter。

第十五章:OpenCV高级特性

  • Ex1FaceDetection -使用预训练的深度学习神经网络模型检测图像中的人脸。

其他通用技术

  • OpenCVUtils -读取和写入图像文件,显示图像,绘制图像的特征,OpenCV图像和数据表示之间的转换。

Why Scala?

之所以选择Scala,是因为它比Java更具表现力。您可以用更少的代码获得相同的结果。更小的样板代码使示例更容易阅读和理解。编译后的Scala代码速度很快,类似于Java和c++。

与Java或c++不同,Scala支持编写脚本——无需显式编译即可执行的代码。Scala也有一个控制台,称为REPL,可以在其中输入单行代码并当场执行。这两个特性使得在Scala中构建基于opencv的程序比在Java中更容易。最后但并非最不重要的一点是,IDE对Scala的支持达到了成熟的程度,允许轻松地创建、修改和执行Scala代码。特别是,用于JetBrains IDEA的Scala插件工作得非常好。还有对Eclipse和NetBeans的Scala支持。

学习地址

https://github.com/bytedeco/javacv

Welcome to OpenCV Java Tutorials documentation! — OpenCV Java Tutorials 1.0 documentation

GitHub - bytedeco/javacv-examples: Examples of using JavaCV / OpenCV library on Java Virtual Machine

关于类、API等如果有疑问可以看考openCV、FFmpeg的方法介绍,javaCV只不过是对它们的封装,或者直接问ChatGPT吧,简单高效!

图像简单处理代码示例

图像处理的API主要集中在opencv-4.6.0-1.5.8.jar包下,该包有两个目录“bytedeco.opencv”与“opencv”,两个package下有许多同名的类与静态方法,请尽量采用“bytedeco.opencv”package下的类与方法。

1.打开保存一张图

// 打开一张图
Mat image = imread("D:\\2projects_database\\javacvdemo\\src\\main\\java\\com\\example\\img\\future_city.jpg");
// 保存图像       imwrite("D:\\2projects_database\\javacvdemo\\src\\main\\java\\com\\example\\img\\future_city_add_text.jpg", image);

2.画直线

/*** 画直线* @param image 图片* @param x1 起点横坐标* @param y1 起点纵坐标* @param x2 终点横坐标* @param y2 终点纵坐标* @param color 线条颜色*/
public static void drawLine(Mat image, int x1, int y1, int x2, int y2, Scalar color) {Point pt1 = new Point(x1, y1);Point pt2 = new Point(x2, y2);line(image, pt1, pt2, color);
}

3.画圆圈

/*** 画圆圈* @param image 图像* @param x 圆心横坐标* @param y 圆心纵坐标* @param radius 半径* @param color 线条颜色* @param thickness 线条厚度* @param lineType 线条类型* @param shift 坐标值的小数位数*/
public static void drawCircle(Mat image, int x, int y, int radius, Scalar color, int thickness, int lineType, int shift) {Point center = new Point(x, y);circle(image, center, radius, color, thickness, lineType, shift);
}

4.画折现

/*** 画折现* @param image 图像* @param points 端点数组* @param color 线条颜色*/
public static void drawCurve(Mat image, Point[] points, Scalar color) {for (int i = 0; i < points.length - 1; i++) {line(image, points[i], points[i+1], color);}
}

5.添加文字水印

/*** 添加文字水印* @param image 图像* @param text 文字内容* @param position 文字位置* @param fontFace 字体类型* @param fontScale 字体大小* @param color 字体颜色*/
public static void addTextWatermark(Mat image, String text, Point position, int fontFace, double fontScale, Scalar color) {putText(image, text, position, fontFace, fontScale, color);
}

6.裁剪并局部放大

/*** 裁剪图像并局部放大* @param image 图像* @param x 起始位置横坐标* @param y 起始位置纵坐标* @param width 裁剪宽度* @param height 裁剪高度* @param zoomFactor 放大倍数*/
public static void cropAndZoomImage(Mat image, int x, int y, int width, int height, int zoomFactor) {Rect roi = new Rect(x, y, width, height);Mat croppedImage = new Mat(image, roi);resize(croppedImage, croppedImage, new Size(width*zoomFactor, height*zoomFactor));// 保存图像imwrite("D:\\2projects_database\\javacvdemo\\src\\main\\java\\com\\example\\img\\cropAndZoomImage.png", croppedImage);System.out.println("resize rows:" + croppedImage.rows());System.out.println("resize cols:" + croppedImage.cols());
}

7.人脸检测

package com.example.img.code;import org.bytedeco.opencv.opencv_core.*;
import org.bytedeco.opencv.opencv_objdetect.CascadeClassifier;
import static org.bytedeco.opencv.global.opencv_imgcodecs.imread;
import static org.bytedeco.opencv.global.opencv_imgcodecs.imwrite;
import static org.bytedeco.opencv.global.opencv_imgproc.LINE_8;
import static org.bytedeco.opencv.global.opencv_imgproc.rectangle;/*** @Author yrz* @create 2023/5/12 11:22* @Description TODO*/public class FaceDetector {public static void main(String[] args) {// Load the imageMat image = imread("D:/2projects_database/javacvdemo/src/main/java/com/example/img/face.jpg");// Load the face cascade classifierCascadeClassifier faceCascade = new CascadeClassifier("D:/2projects_database/javacvdemo/src/main/java/com/example/img/haarcascade_frontalface_alt.xml");// Detect faces in the imageRectVector faceDetections = new RectVector();faceCascade.detectMultiScale(image, faceDetections);// Draw a rectangle around each detected facefor (Rect rect : faceDetections.get()) {rectangle(image, new Point(rect.x(), rect.y()), new Point(rect.x() + rect.width(), rect.y() + rect.height()),new Scalar(0, 255, 0, 0), 2, LINE_8, 0);}// Save the image with the detected facesimwrite("D:/2projects_database/javacvdemo/src/main/java/com/example/img/face_output.jpg", image);}
}

视频简单处理代码示例

视频处理的API主要集中在javacv-1.5.8.jar包下。

1.打开视频文件

/*** 打开视频文件* @param filename*/
public static void readDisplayVideo(String filename){FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(filename);// Open video video filetry {grabber.start();} catch (FFmpegFrameGrabber.Exception e) {e.printStackTrace();}// Prepare window to display framesCanvasFrame canvasFrame = new CanvasFrame("Extracted Frame", 1);canvasFrame.setCanvasSize(grabber.getImageWidth(), grabber.getImageHeight());// Exit the example when the canvas frame is closedcanvasFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);long delay = Math.round(1000d / grabber.getFrameRate());// Read frame by frame, stop early if the display window is closedFrame frame;try {while ((frame = grabber.grab()) != null && canvasFrame.isVisible()) {// Capture and show the framecanvasFrame.showImage(frame);// DelayThread.sleep(delay);}// Close the video filegrabber.release();} catch (FFmpegFrameGrabber.Exception e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}
}

2.抓取视频指定时间的帧保存为图像

/*** 抓取视频指定时间的帧保存为图像* @param videoPath* @param imagePath* @param timeInSeconds*/
public static void grabFrameAtTime(String videoPath, String imagePath, long timeInSeconds) {FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(videoPath);Java2DFrameConverter converter = new Java2DFrameConverter();try {grabber.start();grabber.setTimestamp(timeInSeconds);Frame grab = grabber.grabImage();BufferedImage bufferedImage = converter.getBufferedImage(grab, converter.getBufferedImageType(grab) ==BufferedImage.TYPE_CUSTOM ? 1.0 : 1.0, false, null);saveImage(bufferedImage, imagePath);grabber.stop();} catch (Exception e) {e.printStackTrace();}
}
public static void saveImage(BufferedImage image, String imagePath) {try {ImageIO.write(image, "jpg", new File(imagePath));} catch (IOException e) {e.printStackTrace();}
}

3.录屏

/*** 录屏* @param filename 文件名称* @param seconds 时长*/
public static void recordScreen(String filename, int seconds) {final int FRAME_RATE = 30;final Dimension SCREEN_SIZE = Toolkit.getDefaultToolkit().getScreenSize();// 创建录屏对象,并设置相关属性FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(filename, SCREEN_SIZE.width, SCREEN_SIZE.height);recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);recorder.setFormat("mp4");recorder.setFrameRate(FRAME_RATE);Java2DFrameConverter converter = new Java2DFrameConverter();try {// 初始化录屏对象recorder.start();Robot robot = new Robot();BufferedImage screenShot;// 系统当前时间LocalDateTime now = LocalDateTime.now();System.out.println(now);// 30秒后LocalDateTime plus = now.plus(seconds, ChronoUnit.SECONDS);System.out.println(plus);// 开始录制while (true) {// 获取屏幕截图并写入文件screenShot = robot.createScreenCapture(new Rectangle(SCREEN_SIZE));recorder.record(converter.getFrame(screenShot));// 停止时间LocalDateTime time = LocalDateTime.now();if(plus.isBefore(time)){System.out.println(time);break;}}} catch (Exception e) {e.printStackTrace();} finally {// 关闭录制器try {recorder.stop();} catch (Exception e) {e.printStackTrace();}}
}

4.给视频添加水印

/*** 给视频添加水印* @param filename* @param outname* @param picName* @throws Exception*/public static void addWatermark (String filename, String outname, String picName) throws Exception {// Load the videoFFmpegFrameGrabber grabber = new FFmpegFrameGrabber(filename);grabber.start();// Create a new video recorderFFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outname, grabber.getImageWidth(), grabber.getImageHeight(), grabber.getAudioChannels());recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);recorder.setFormat("mp4");recorder.setFrameRate(grabber.getFrameRate());// 开启录制recorder.start();// Create a new Java2DFrameConverterJava2DFrameConverter converter = new Java2DFrameConverter();// Create a new BufferedImage to hold the watermark image// 图片水印BufferedImage watermarkImage = ImageIO.read(new File(picName));// 自定义文字水印
//        BufferedImage watermarkImage = createWatermarkImage("Hello, world!", new Font("Arial", Font.BOLD, 50),
//                Color.WHITE, new Color(0, 0, 0, 0));// Loop through each frame in the videoFrame frame;while ((frame = grabber.grabFrame()) != null) {// Convert the frame to a BufferedImageBufferedImage image = converter.getBufferedImage(frame);if(image == null){continue;}// Create a new Graphics2D object to draw the watermarkGraphics2D g2d = image.createGraphics();// Draw the watermark on the imageg2d.drawImage(watermarkImage, 0, 0, null);// Dispose of the Graphics2D objectg2d.dispose();// Convert the BufferedImage back to a Frame and write it to the output videorecorder.record(converter.convert(image));}// Stop the grabber and recordergrabber.stop();grabber.release();recorder.stop();recorder.release();}private static BufferedImage createWatermarkImage(String text, Font font, Color foreground, Color background) {FontRenderContext frc = new FontRenderContext(null, true, true);TextLayout layout = new TextLayout(text, font, frc);Rectangle2D bounds = layout.getBounds();BufferedImage image = new BufferedImage((int) bounds.getWidth(), (int) bounds.getHeight(), BufferedImage.TYPE_INT_ARGB);Graphics2D g2d = image.createGraphics();g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);if (background != null) {g2d.setBackground(background);g2d.clearRect(0, 0, image.getWidth(), image.getHeight());}g2d.setFont(font);g2d.setColor(foreground);layout.draw(g2d, 0, -(float) bounds.getY());if (background != null) {ColorConvertOp colorConvert = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_sRGB),null);colorConvert.filter(image, image);}g2d.dispose();return image;}

Java音视频处理——JavaCV相关推荐

  1. JAVA音视频解决方案----视频基础知识

    序言 公司现在在做汽车终端的平台,需要了解交通部808,1078的终端协议.  尤其是1078是关于音视频的协议.故此开始入坑java的音视频解决方案.本系列文章涉及一个完整的音视频服务搭建.大概整理 ...

  2. java音视频开发技术_FFmpeg音视频核心技术精讲与实战

    百度网盘2 D2 h2 i; n# o0 D# M* C! [: B1 M 第1章 学习指南[课程提供200+问题与答案库]4 a# t% {  h6 ^: E# O [你遇到的坑,别人已经出坑了,课 ...

  3. java音视频处理类,Android Java实时音视频SDK自定义视频前处理功能 - 开发者中心 - ZEGO即构科技...

    自定义视频前处理 更新时间:2021-02-07 17:47 1 功能简介 当 SDK 自带的美颜无法满足需求,例如需要做挂件.贴纸,或者美颜效果无法达到预期时,推荐开发者使用自定义视频前处理功能.该 ...

  4. JAVA音视频解决方案----部标1078 808 视频解决方案

    序言 经历了3周的研究,终于搞出来了. 首先各个终端厂家的推流协议可能不是统一的,因为1078也分2014版和2016版.所以在解析tcp包的时候需要自己注意.如需源码请联系cuiyaonan2000 ...

  5. JAVA音视频解决方案----音频处理方案

    序言 音频的处理需要先了解音频的处理流程.如:你需要知道模拟信号到数字信号的处理流程.才能针对性的发现问题以及解决问题.处理方法与处理视频是一样的. 方案1 2个线程.每个线程独立有一个Grab和Re ...

  6. JAVA音视频解决方案----音频基础知识

    序言 参考2个博客地址: https://blog.csdn.net/byxdaz/article/details/80703970 https://www.jianshu.com/p/f56114d ...

  7. 只知道用c++搞音视频?来来来,javacv了解一下

    javacv是什么?javacv技术栈能做什么? 大家肯定对javacv很感兴趣,恰巧博主对javacv稍有涉猎,这就来给各位小伙伴们安利一番,javacv到底可以做什么,可以在哪些领域独领风骚. j ...

  8. 笔耕不辍,持续更新六年的高质量java流媒体音视频和人工智能教程值得大家拥有

    高度内卷时代,躺平是不可能躺平的,这辈子都不可能躺平. 身为java程序猿还停留在只会增删改查吗?写了几年代码还是只会spring全家桶?在java这个拥挤赛道中想要以技术立身于不败之地,不如来看看j ...

  9. javaCV入门指南:调用FFmpeg原生API和JavaCV是如何封装了FFmpeg的音视频操作?

    JavaCV入门指南系列: JavaCV入门指南:序章(看完本章后,不想看原理的小伙伴可直接跳转到<快速上手篇>) JavaCV入门指南:调用FFmpeg原生API和JavaCV是如何封装 ...

最新文章

  1. Apache 的prefork MPM和worker MPM
  2. SAP PM整修流程
  3. 你的企业客户服务,离卓越还有多远?
  4. 最小二乘抛物线拟合原理及证明
  5. iOS开发学无止境 - 异步图片加载优化与常用开源库分析
  6. jmeter3.3—插件管理器的安装
  7. Spring 社区的唯一一个国产开源项目 - Spring Cloud Alibaba 毕业了
  8. 从文件夹中批量抽取(复制or剪切)文件 批处理脚本
  9. 过滤Android工程中多余的资源文件
  10. http 使用curl发起https请求 error 60 51
  11. windows和Linux虚拟机或者云主机之间传输文件
  12. 关于app跳转vueh5页面时获取url附带的参数_h5唤起app技术deeplink方案总结
  13. sim800a指令_SIM800A_硬件设计手册-LCSC.PDF
  14. RabbitMq Direct exchange路由模型
  15. RGB-Infrared Cross-Modality Person Re-Identification---阅读
  16. 数据结构(C语言)课设1——单位员工通讯录管理系统(线性表应用)
  17. ubuntu12.04下安装matlab
  18. android 使用DDMS
  19. 最大公共子串及其长度计算
  20. php程序员作息时间表,公认最健康的作息时间表!

热门文章

  1. xadsafe做暗刷_手把手教你如何去掉网吧广告之万象OL篇_XADSAFE
  2. 算法入门——小学生算数
  3. 教你怎么利用豆瓣推广引流粉丝
  4. 【Java多线程】Java线程状态及转换方法详解
  5. 服务器搭建npm私服
  6. 取代 Mybatis Generator,这款代码生成神器配置更简单,开发效率更高
  7. Maxscale读写分离集群过渡PXC集群
  8. matlab肺部病灶提取,肺结节CT影像特征提取(四)——肺结节CT影像特征提取MATLAB代码实现...
  9. [OS] ESXi安装和配置
  10. 喜大普奔,知了堂4月信安预科班顺利开课!