Java音视频处理——JavaCV

目录

 

简介

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;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/35108.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大模型与AIGC峰会!知名专家学者现场论道!

6月30日-7月1日&#xff0c;在由稀土掘金开发者社区主办的稀土开发者大会上&#xff0c;邀你与专业前沿的嘉宾面对面交流&#xff01;6月30日上午的主会场&#xff0c;北京大学王选计算机研究所教授、CCF 自然语言处理专委会秘书长万小军&#xff0c;会带来关于AIGC的重磅分享。…

第三周C++与PCL的学习(3.13-3.19)

目录 第一天3.13 星期一 Qt安装于简单应用 第二天3.14 星期二 ui闪退的解决、PCL的pri文件配置 第三天3.15 星期三 百度地图api的调用以及在Qt中的配置 第四天3.16 星期四 PCM软件的学习 第五天3.17 星期五 数据库的建立和使用 第六天3.18 星期六 Kinect融合、时…

利用微软Bing进行AI绘画

我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版&#xff0c;欢迎购买。点击进入详情 Link: http://bing.com/create

为什么说买彩票是交智商税?

很多人都有一夜暴富的幻想&#xff0c;梦想着好运来临&#xff0c;从此咸鱼翻身&#xff0c;这种心态可以理解&#xff0c;现在经济不景气&#xff0c;工作又辛苦&#xff0c;钱越来越难赚&#xff0c;想来想去能够实现财富自由最轻松的方式就是买彩票了。 我以前也经常买彩票…

腾讯领投英国金融科技创企True Layer 4000万美元融资

【TechWeb】6月4日消息&#xff0c;据国外媒体报道&#xff0c;腾讯将向一家成立5年的英国金融科技初创企业注资数千万美元&#xff0c;这笔投资将进一步提振伦敦的金融科技行业。 据业内人士透露&#xff0c;腾讯领投True Layer 4000万美元融资。新加坡主权财富基金淡马锡也可…

比起商汤IPO,我们更关心那1亿美金和C轮融资的背后大料

昨日&#xff08;11月23日&#xff09;&#xff0c;营长的朋友圈被《商汤科技计划IPO 并将在美设立研发中心》刷屏了。甚至有媒体曝“商汤科技最早明年进行IPO”。 这条新闻最早由路透社爆出来。对此&#xff0c;AI科技大本营向商汤科技官方求证是否已经开始为IPO做相关准备&a…

信音电子在创业板IPO:募资约9亿元,预计上半年收入约4.3亿元

7月17日&#xff0c;信音电子&#xff08;中国&#xff09;股份有限公司&#xff08;下称“信音电子”&#xff0c;SZ:301329&#xff09;在深圳证券交易所创业板上市。本次上市&#xff0c;信音电子的发行价为21.00元/股&#xff0c;发行数量为为4300万股&#xff0c;募资总额…

【金猿投融展】GrowingIO——一站式数据增长引擎整体方案服务商

投融资项目GrowingIO 本项目由GrowingIO投递并参与“数据猿年度金猿策划活动——2021大数据产业最具投资价值榜单及奖项”评选。 数据智能产业创新服务媒体 ——聚焦数智 改变商业 GrowingIO 创立于2015年5月&#xff0c;是国内领先的一站式数据增长引擎方案服务商&#xff0c…

弘玑Cyclone完成1.5亿美元C轮融资,创行业单笔融资额最大记录

近日&#xff0c;全球领先的RPA公司&#xff0c;超自动化&#xff08;Hyperautomation&#xff09;行业的领导者弘玑Cyclone完成1.5亿美元C轮融资&#xff0c;成单笔融资额最大的中国RPA厂商。本轮融资由CMC资本、高盛资产管理领投&#xff0c;Lavender Hill Capital Partners&…

普源精电通过注册:拟募资7.5亿 高瓴与招银是股东

雷递网 雷建平 3月7日报道 普源精电科技股份有限公司&#xff08;简称&#xff1a;“普源精电”&#xff09;日前通过注册&#xff0c;预计近期在科创板上市&#xff0c;计划募资7.5亿元。 其中1.5亿元用于以自研芯片组为基础的高端数字示波器产业化项目&#xff0c;1.61亿元用…

康力源在创业板提交注册:预计全年收入同比下滑,衡墩建持股98%

12月4日&#xff0c;江苏康力源体育科技股份有限公司&#xff08;下称“康力源”&#xff09;在深圳证券交易所创业板提交招股书&#xff08;注册稿&#xff09;。据贝多财经了解&#xff0c;康力源于2021年11月12日在创业板递交招股书&#xff0c;2022年8月11日获得上市委会议…

思林杰科技通过注册:应收账款余额1.87亿 占营收比例160%

雷递网 雷建平 2月18日报道 广州思林杰科技股份有限公司&#xff08;简称&#xff1a;“思林杰科技”&#xff09;日前通过注册&#xff0c;准备在科创板上市&#xff0c;计划募资5.57亿元。 其中&#xff0c;2.67亿元用于嵌入式智能仪器模块扩产建设项目&#xff0c;1.6亿元用…

观远数据完成2.8亿元C轮融资

近日,一站式数据分析与商业智能平台提供商——杭州观远数据有限公司(以下简称“观远数据”)宣布完成新一轮2.8亿元C轮融资。本轮融资由全球知名的老虎环球基金(Tiger Global)领投,红杉中国、线性资本、襄禾资本、独秀资本(Unicorn Capital Partners)等老股东全线跟投。据观远数…

惠通科技冲刺深交所:年营收5亿 严旭明与张建纲为实控人

雷递网 雷建平 6月18日报道 扬州惠通科技股份有限公司&#xff08;简称&#xff1a;“惠通科技”&#xff09;日前递交招股书&#xff0c;准备在深交所创业板上市。 惠通科技计划募资4亿元&#xff0c;其中&#xff0c;1.5亿元用于高端化工装备生产线智能化升级改造项目&#x…

巨潮资讯网上市公司股票讯息批量下载

分析网页 可以看见网站搜索框这里运用了异步JavaScript渲染来报证不刷新整个页面的情况下来刷新数据&#xff0c;这样我们就可直接打开浏览器开发工具找到Ajax请求&#xff0c;也就是图中我点击的位置&#xff0c;然后可以看到请求体里面有params数&#xff0c;这个参数一般是用…

智融科技冲刺科创板上市:拟募资4.5亿元,产品单价和毛利率高

4月15日&#xff0c;珠海智融科技股份有限公司&#xff08;下称“智融科技”&#xff09;披露招股说明书&#xff08;申报稿&#xff09;&#xff0c;并获得科创板受理。本次上市&#xff0c;智融科技拟发行股份不超过1500万股&#xff0c;占发行后总股本的比例不低于25%&#…

湖北万润递交招股书上会稿,2021年实现扭亏为盈

2022年6月2日&#xff0c;湖北万润新能源科技股份有限公司&#xff08;下称 “湖北万润”&#xff09;在科创板更新招股书并递交上会稿。这意味着&#xff0c;湖北万润的上市进程进入新阶段。在此之前&#xff0c;该公司已经历经三轮问询。 公开信息显示&#xff0c;湖北万润成…

清越科技将开启申购:预计募资约8亿元,高裕弟为实际控制人

12月19日&#xff0c;苏州清越光电科技股份有限公司&#xff08;下称“清越科技”&#xff0c;SH:688496&#xff09;将开启申购。据贝多财经了解&#xff0c;清越科技本次上市的发行价格为9.16元/股&#xff0c;发行数量为9000万股&#xff0c;募资总额约为8.24亿元&#xff0…

​杭州蓝然创业板IPO终止:应收账款、存货账面高,楼永通为实控人​

近日&#xff0c;杭州蓝然技术股份有限公司&#xff08;下称“杭州蓝然”&#xff09;向深圳证券交易所提交了撤回在创业板上市申请文件的申请。同时&#xff0c;其保荐机构也撤回保荐。12月23日&#xff0c;深圳证券交易所做出决定&#xff0c;终止对杭州蓝然在创业板IPO的审核…

催收公司承信科技申请纳斯达克IPO上市,募资1500万美元

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;来自苏州的催收公司&#xff0c;承信信息科技有限公司&#xff08;下称“承信科技”&#xff09;近期已向美国证券交易委员会&#xff08;SEC&#xff09;提交招股书&#xff0c;申请在纳斯达克I…