JavaCV详尽教程
从入门到精通的Java计算机视觉开发指南
download 安装与配置
Maven依赖配置
JavaCV通过Maven中央仓库提供,只需在pom.xml中添加以下依赖:
<!-- JavaCV核心库 --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv</artifactId> <version>1.5.7</version> </dependency> <!-- 根据需要添加特定平台依赖 --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>opencv</artifactId> <version>4.5.5-1.5.7</version> <classifier>windows-x86_64</classifier> // 根据平台选择 </dependency>
平台特定依赖
JavaCV支持多种平台,需要根据目标平台选择相应的预编译库:
- Windows: windows-x86_64, windows-x86
- Linux: linux-x86_64, linux-armhf, linux-arm64
- macOS: macosx-x86_64, macosx-arm64
- Android: android-arm, android-x86
IDE配置
1
在IntelliJ IDEA或Eclipse中创建新的Maven项目
2
添加上述Maven依赖到pom.xml文件
3
刷新项目依赖,确保所有库正确下载
4
设置JVM参数(可选):-Djava.library.path=/path/to/native/libs
api 核心API介绍
主要组件
组件 | 功能描述 | 主要用途 |
---|---|---|
Frame | 表示图像或视频帧的基本数据结构 | 存储图像数据、时间戳等元信息 |
FrameGrabber | 用于从各种源捕获帧的抽象类 | 从摄像头、视频文件、图像序列获取帧 |
FrameRecorder | 用于将帧写入各种目标的抽象类 | 将帧保存为视频文件、图像序列 |
CanvasFrame | 用于显示图像帧的GUI组件 | 实时预览、调试显示 |
OpenCVFrameConverter | 在Frame和OpenCV Mat之间转换 | 与OpenCV原生API互操作 |
FrameGrabber实现类
- OpenCVFrameGrabber:使用OpenCV后端,支持多种视频格式和摄像头
- FFmpegFrameGrabber:基于FFmpeg,支持更广泛的视频格式和网络流
- DC1394FrameGrabber:专用于IEEE 1394工业相机
- FlyCaptureFrameGrabber:用于Point Grey工业相机
- OpenKinectFrameGrabber:用于Kinect深度相机
image 图像处理示例
基本图像操作
import org.bytedeco.javacv.*; import org.bytedeco.opencv.opencv_core.*; import static org.bytedeco.opencv.global.opencv_imgcodecs.*; import static org.bytedeco.opencv.global.opencv_imgproc.*; public class BasicImageOperations { public static void main(String[] args) throws Exception { // 1. 加载图像 OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat(); Mat image = imread("input.jpg"); // 2. 转换为灰度图像 Mat grayImage = new Mat(); cvtColor(image, grayImage, COLOR_BGR2GRAY); // 3. 图像缩放 Mat resizedImage = new Mat(); Size size = new Size(image.cols() / 2, image.rows() / 2); resize(image, resizedImage, size); // 4. 图像旋转 Mat rotatedImage = new Mat(); Point center = new Point(image.cols() / 2, image.rows() / 2); Mat rotationMatrix = getRotationMatrix2D(center, 45, 1.0); warpAffine(image, rotatedImage, rotationMatrix, image.size()); // 5. 边缘检测 Mat edges = new Mat(); Canny(grayImage, edges, 100, 200); // 6. 保存结果 imwrite("gray.jpg", grayImage); imwrite("resized.jpg", resizedImage); imwrite("rotated.jpg", rotatedImage); imwrite("edges.jpg", edges); // 7. 显示结果 CanvasFrame canvas = new CanvasFrame("Image Processing", 1); canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE); // 显示原始图像 canvas.showImage(converter.convert(image)); canvas.waitKey(2000); // 显示边缘检测结果 canvas.showImage(converter.convert(edges)); canvas.waitKey(); } }
图像滤波与增强
import org.bytedeco.opencv.opencv_core.*; import static org.bytedeco.opencv.global.opencv_imgproc.*; // 高斯模糊 Mat blurred = new Mat(); GaussianBlur(image, blurred, new Size(15, 15), 0); // 双边滤波(保边去噪) Mat bilateral = new Mat(); bilateralFilter(image, bilateral, 15, 80, 80); // 亮度与对比度调整 Mat adjusted = new Mat(); image.convertTo(adjusted, CV_8UC3, 1.5, 30); // 对比度1.5,亮度+30 // 直方图均衡化(增强对比度) Mat equalized = new Mat(); equalizeHist(grayImage, equalized); // 形态学操作 Mat morphed = new Mat(); Mat kernel = getStructuringElement(MORPH_RECT, new Size(5, 5)); morphologyEx(image, morphed, MORPH_CLOSE, kernel);
videocam 视频处理示例
视频读取与处理
import org.bytedeco.javacv.*; import org.bytedeco.opencv.opencv_core.*; import static org.bytedeco.opencv.global.opencv_imgproc.*; public class VideoProcessing { public static void main(String[] args) throws Exception { // 1. 创建视频抓取器 FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("input.mp4"); grabber.start(); // 2. 获取视频信息 int width = grabber.getImageWidth(); int height = grabber.getImageHeight(); double frameRate = grabber.getVideoFrameRate(); int frameCount = grabber.getLengthInFrames(); System.out.println("视频尺寸: " + width + "x" + height); System.out.println("帧率: " + frameRate); System.out.println("总帧数: " + frameCount); // 3. 创建视频录制器 FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("output.mp4", width, height); recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); recorder.setFormat("mp4"); recorder.setFrameRate(frameRate); recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P. ;✅ recorder.start(); // 4. 创建转换器 OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat(); // 5. 处理每一帧 Frame frame; int processedFrames = 0; while ((frame = grabber.grab()) != null) { // 转换为OpenCV Mat Mat mat = converter.convert(frame); // 处理帧(例如:边缘检测) Mat gray = new Mat(); cvtColor(mat, gray, COLOR_BGR2GRAY); Mat edges = new Mat(); Canny(gray, edges, 100, 200); // 转换回彩色 Mat result = new Mat(); cvtColor(edges, result, COLOR_GRAY2BGR); // 记录处理后的帧 recorder.record(converter.convert(result)); processedFrames++; // 打印进度 if (processedFrames % 100 == 0) { System.out.println("已处理: " + processedFrames + "/" + frameCount + " 帧"); } } // 6. 释放资源 grabber.stop(); recorder.stop(); System.out.println("视频处理完成!"); } }
实时摄像头处理
public class CameraProcessing { public static void main(String[] args) throws Exception { // 1. 创建摄像头抓取器 OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0); // 0表示默认摄像头 grabber.setImageWidth(640); grabber.setImageHeight(480); grabber.start(); // 2. 创建显示窗口 CanvasFrame canvas = new CanvasFrame("Camera Feed", 1); canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE); // 3. 创建转换器 OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat(); // 4. 实时处理循环 Frame frame; while ((frame = grabber.grab()) != null) { // 转换为OpenCV Mat Mat mat = converter.convert(frame); // 应用滤镜(例如:卡通效果) Mat result = applyCartoonEffect(mat); // 显示处理后的帧 canvas.showImage(converter.convert(result)); // 检查窗口是否关闭 if (canvas.isVisible() == false) { break; } } // 5. 释放资源 grabber.stop(); canvas.dispose(); } private static Mat applyCartoonEffect(Mat src) { // 卡通效果实现 Mat imgGray = new Mat(); cvtColor(src, imgGray, COLOR_BGR2GRAY); Mat imgBlur = new Mat(); medianBlur(imgGray, imgBlur, 7); Mat imgEdge = new Mat(); adaptiveThreshold(imgBlur, imgEdge, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 7, 7); Mat imgColor = new Mat(); bilateralFilter(src, imgColor, 15, 80, 80); Mat cartoon = new Mat(); bitwise_and(imgColor, imgColor, cartoon, imgEdge); return cartoon; } }
auto_awesome 高级功能应用
人脸检测与识别
import org.bytedeco.javacv.*; import org.bytedeco.opencv.opencv_core.*; import org.bytedeco.opencv.opencv_objdetect.*; import static org.bytedeco.opencv.global.opencv_imgproc.*; public class FaceDetection { public static void main(String[] args) throws Exception { // 1. 加载人脸检测器 CascadeClassifier faceDetector = new CascadeClassifier(); faceDetector.load("haarcascade_frontalface_alt.xml"); // 2. 打开摄像头 OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0); grabber.start(); // 3. 创建显示窗口 CanvasFrame canvas = new CanvasFrame("Face Detection", 1); canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE); // 4. 创建转换器 OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat(); // 5. 实时人脸检测循环 Frame frame; while ((frame = grabber.grab()) != null) { // 转换为OpenCV Mat Mat mat = converter.convert(frame); // 转换为灰度图像(人脸检测通常在灰度图像上进行) Mat gray = new Mat(); cvtColor(mat, gray, COLOR_BGR2GRAY); // 直方图均衡化(提高检测效果) equalizeHist(gray, gray); // 检测人脸 RectVector faces = new RectVector(); faceDetector.detectMultiScale(gray, faces); // 在图像上标记人脸 for (int i = 0; i < faces.size(); i++) { Rect face = faces.get(i); // 绘制人脸矩形框 rectangle(mat, new Point(face.x(), face.y()), new Point(face.x() + face.width(), face.y() + face.height()), new Scalar(0, 255, 0), 2); // 在人脸上方添加标签 putText(mat, "Face", new Point(face.x(), face.y() - 10), FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(0, 255, 0), 2); } // 显示结果 canvas.showImage(converter.convert(mat)); // 检查窗口是否关闭 if (canvas.isVisible() == false) { break; } } // 6. 释放资源 grabber.stop(); canvas.dispose(); } }
对象跟踪
import org.bytedeco.javacv.*; import org.bytedeco.opencv.opencv_core.*; import org.bytedeco.opencv.opencv_videoio.*; import org.bytedeco.opencv.opencv_video.*; import static org.bytedeco.opencv.global.opencv_imgproc.*; public class ObjectTracking { public static void main(String[] args) throws Exception { // 1. 打开视频或摄像头 OpenCVFrameGrabber grabber = new OpenCVFrameGrabber("input.mp4"); grabber.start(); // 2. 创建显示窗口 CanvasFrame canvas = new CanvasFrame("Object Tracking", 1); canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE); // 3. 创建转换器 OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat(); // 4. 读取第一帧并选择跟踪对象 Frame frame = grabber.grab(); Mat firstFrame = converter.convert(frame); // 让用户选择跟踪区域(这里简化为固定区域) Rect roi = new Rect(300, 200, 100, 100); rectangle(firstFrame, roi.tl(), roi.br(), new Scalar(0, 255, 0), 2); canvas.showImage(converter.convert(firstFrame)); canvas.waitKey(1000); // 5. 初始化跟踪器 Tracker tracker = TrackerKCF.create(); tracker.init(firstFrame, roi); // 6. 跟踪循环 while ((frame = grabber.grab()) != null) { Mat mat = converter.convert(frame); // 更新跟踪器 boolean success = tracker.update(mat, roi); // 绘制跟踪结果 if (success) { rectangle(mat, roi.tl(), roi.br(), new Scalar(0, 255, 0), 2); putText(mat, "Tracking", roi.tl(), FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(0, 255, 0), 2); } else { putText(mat, "Lost", new Point(100, 80), FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(0, 0, 255), 2); } // 显示结果 canvas.showImage(converter.convert(mat)); // 检查窗口是否关闭 if (canvas.isVisible() == false) { break; } } // 7. 释放资源 grabber.stop(); canvas.dispose(); } }