JavaCV详尽教程

JavaCV详尽教程

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

© 2023 JavaCV详尽教程 | 从入门到精通的Java计算机视觉开发指南

发表评论

Only people in my network can comment.
人生梦想 - 关注前沿的计算机技术 acejoy.com 🐾 步子哥の博客 🐾 背多分论坛 🐾 知差(chai)网 🐾 DeepracticeX 社区 🐾 老薛主机 🐾 智柴论坛 🐾