• 如何系列 如何使用OpenCV进行图像操作


    简介

    OpenCV (Open Source Computer Vision Library) 是一个计算机视觉和机器学习的开源库,其提供了丰富的图像处理和计算机视觉算法。OpenCV 最初是为 C++ 编写的,但现在也支持 Java 编程语言。

    你就认为是个增强版的ps工具

    以下是一些 OpenCV 的功能和能够实现的任务:

    1. 图像读取和显示:OpenCV 可以读取多种图像格式,并提供图像显示的功能。
    2. 图像处理:OpenCV 提供了各种图像处理工具,包括滤波、增强、色彩转换、几何变换等。
    3. 特征检测与描述:OpenCV 可以检测图像中的关键点,并计算用于描述这些关键点的特征向量,例如 SIFT、SURF、ORB 等。
    4. 图像匹配与识别:OpenCV 允许你使用特征匹配算法来识别或跟踪物体,也可以进行模板匹配。
    5. 物体检测:OpenCV 提供了各种物体检测器,如人脸检测、车辆检测、目标检测等。
    6. 形态学操作:用于处理二值图像,包括膨胀、腐蚀、开运算、闭运算等。
    7. 图像分割:OpenCV 支持图像分割技术,如阈值分割、边缘检测、区域生长等。
    8. 图像重映射:可以通过重映射函数将图像的像素位置重新映射到新的位置。
    9. 颜色空间转换:允许在不同颜色空间之间进行转换,如 RGB 到 HSV、灰度等。
    10. 图像拼接:用于将多幅图像拼接成全景图像,支持水平和垂直拼接。
    11. 摄像头捕捉和视频处理:OpenCV 可以从摄像头捕捉实时视频,并进行视频处理、分析和流处理。
    12. 计算机视觉算法:OpenCV 包含各种计算机视觉算法,如光流、相机标定、三维重建、立体视觉等。
    13. 机器学习集成:OpenCV 可以与机器学习库集成,如 TensorFlow 和 PyTorch,以构建深度学习模型并进行推理。
    14. 图像绘制和标注:用于在图像上绘制文本、线条、形状等,以标注图像。
    15. 背景减除:用于从图像中分离前景对象和背景。
    16. 图像相似度度量:可以计算两幅图像之间的相似度,如结构相似性指数(SSIM)等。
    17. 多视图几何:支持多视图几何算法,如立体校正、三角测量等。
    18. 人脸识别与追踪:OpenCV 提供了人脸检测、识别和追踪的功能。
    19. 深度学习集成:OpenCV 提供了深度学习模型的加载、推理和微调功能,支持多种深度学习框架。
    20. 图像处理管道和流程:可以构建复杂的图像处理管道,以进行自动化图像处理和分析。

    这些只是 OpenCV 提供的一些功能和应用示例。OpenCV 在计算机视觉和图像处理领域具有广泛的应用,可用于图像编辑、机器视觉、自动驾驶、医学图像分析、安全监控、虚拟现实等多个领域。你可以根据具体项目需求,结合 OpenCV 的功能来完成各种图像处理和计算机视觉任务。

    集成

    1.添加Maven依赖项

    <dependency>
        <groupId>org.openpnp</groupId>
        <artifactId>opencv</artifactId>
        <version>4.7.0-0</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.添加动态库

    // 会从jar内复制对应的动态库到临时目录
    // 并调用System.loadLibrary(org.opencv.core.Core.NATIVE_LIBRARY_NAME);
    nu.pattern.OpenCV.loadShared();
    
    • 1
    • 2
    • 3

    代码示例

    • Mat 类表示 n 维密集数值单通道或多通道数组。 它可用于存储实值或复值向量和矩阵、灰度或彩色图像、体素体积、向量场、点云、张量、直方图。

    加载和显示图像

    要在 Java 中加载和显示图像,可以使用 imread 和 imshow 函数。以下是一个简单的示例代码:

    import org.opencv.core.Core;
    import org.opencv.core.Mat;
    import org.opencv.highgui.HighGui;
    public class ImageProcessing {
        public static void main(String[] args) {
            nu.pattern.OpenCV.loadShared();
            // 加载图像
            Mat image = org.opencv.imgcodecs.Imgcodecs.imread("path/to/image.jpg");
            // 显示图像
            HighGui.imshow("Image", image);
            // 等待用户按下任意键关闭窗口
            HighGui.waitKey();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    编辑和保存图像

    import org.opencv.core.Core;
    import org.opencv.core.Mat;
    import org.opencv.imgcodecs.Imgcodecs;
    import org.opencv.imgproc.Imgproc;
    public class Main {
      public static void main(String[] args) {
        // 加载 OpenCV 库
        nu.pattern.OpenCV.loadShared();
        // 读取图像
        Mat image = Imgcodecs.imread("images/_abc.png");
        // 画直线 图片,线段的第一个点,线段的第二个点,线段的颜色,线的宽度
        Imgproc.line(image, new Point(0, 0), new Point(image.cols(), image.rows()), new Scalar(0, 0, 255), 2);
        // 保存图像
        Imgcodecs.imwrite("images/_abc2.png", image);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    边缘检测

    边缘检测是一种常用的图像分析技术,可以用于检测图像中的边缘和轮廓。以下是一个示例代码:

    import org.opencv.core.Mat;
    import org.opencv.core.Size;
    import org.opencv.highgui.HighGui;
    import org.opencv.imgcodecs.Imgcodecs;
    import org.opencv.imgproc.Imgproc;
    public class Test {
        public static void main(String[] args) {
            // 加载 OpenCV 库
            nu.pattern.OpenCV.loadShared();
            // 加载图像
            Mat image = Imgcodecs.imread("images/_abc.png");
            // 从彩色转换为灰度图像。这是因为边缘检测通常在灰度图像上执行,因为它更容易处理。
            Mat edges = new Mat();
            Imgproc.cvtColor(image, edges, Imgproc.COLOR_BGR2GRAY);
            // 对灰度图像应用了高斯模糊(Gaussian Blur)它可以帮助减少图像中的噪声,从而产生更干净的边缘。
            Imgproc.GaussianBlur(edges, edges, new Size(5, 5), 1.5, 1.5);
            // 应用边缘检测算法 输入图像、输出图像和两个阈值
            Imgproc.Canny(image, edges, 100, 200);
            // 显示边缘图像
            HighGui.imshow("Edges", edges);
            HighGui.waitKey();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    图片属性

    import org.opencv.core.CvType;
    import org.opencv.core.Mat;
    import org.opencv.imgcodecs.Imgcodecs;
    
    public class Test {
    
        public static void main(String[] args) {
            // 加载 OpenCV 库
            nu.pattern.OpenCV.loadShared();
            // 加载图像
            Mat image = Imgcodecs.imread("images/_abc.png");
            // 获取图像的宽度和高度
            int width = image.width();
            int height = image.height();
            // 获取图像的通道数(BGR 图像通常为3)
            int numChannels = image.channels();
            // 获取图像的位深度(通常为8位无符号整数)
            int depth = image.depth();
            // 打印图像属性
            System.out.println("Image Width: " + width);
            System.out.println("Image Height: " + height);
            System.out.println("Number of Channels: " + numChannels);
            System.out.println("Image Depth: " + CvType.typeToString(depth));
        }
    }
    ---
    Image Width: 150
    Image Height: 50
    Number of Channels: 3
    Image Depth: CV_8UC1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    图像旋转

    旋转图像以进行校正或调整方向。

    import org.opencv.core.Mat;
    import org.opencv.core.Point;
    import org.opencv.highgui.HighGui;
    import org.opencv.imgcodecs.Imgcodecs;
    import org.opencv.imgproc.Imgproc;
    public class Test {
        public static void main(String[] args) {
            // 加载 OpenCV 库
            nu.pattern.OpenCV.loadShared();
            // 加载图像
            Mat image = Imgcodecs.imread("images/_abc.png");
            double angle = 30; // 旋转角度
            Point center = new Point(image.cols() / 2, image.rows() / 2);
            Mat rotationMatrix = Imgproc.getRotationMatrix2D(center, angle, 1.0);
            Imgproc.warpAffine(image, image, rotationMatrix, image.size());
            // 显示图像
            HighGui.imshow("Image", image);
            // 等待用户按下任意键关闭窗口
            HighGui.waitKey();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    图像缩放

    调整图像的大小。

    Size newSize = new Size(newWidth, newHeight);
    Imgproc.resize(image, image, newSize);
    
    • 1
    • 2

    图像拼接

    将多个图像水平或垂直拼接在一起。

    List<Mat> imagesToConcat = new ArrayList<>();
    // 添加要拼接的图像到列表中
    Mat resultImage = new Mat();
    Core.hconcat(imagesToConcat, resultImage); // 或者使用 Core.vconcat 进行垂直拼接
    
    • 1
    • 2
    • 3
    • 4

    颜色空间转换

    将图像从一种颜色空间转换为另一种,例如从 BGR 到 HSV。

    Imgproc.cvtColor(image, image, Imgproc.COLOR_BGR2HSV);
    
    • 1

    图像模糊平滑化

    图像模糊(平滑化)是一种图像处理技术,可以减少图像中的噪声或细节,使图像变得更加平滑或模糊。OpenCV 提供了多种图像模糊方法,其中最常见的是高斯模糊和均值模糊。

    import org.opencv.core.Core;
    import org.opencv.core.Mat;
    import org.opencv.imgcodecs.Imgcodecs;
    import org.opencv.imgproc.Imgproc;
    
    public class GaussianBlurExample {
        public static void main(String[] args) {
            System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    
            // 读取图像
            String imagePath = "path/to/your/image.jpg";
            Mat image = Imgcodecs.imread(imagePath);
    
            if (image.empty()) {
                System.out.println("Could not open or find the image");
                return;
            }
    
            // 应用高斯模糊
            Imgproc.GaussianBlur(image, image, new org.opencv.core.Size(5, 5), 0);
            // blur均值模糊
            // medianBlur中值模糊
            // bilateralFilter双边模糊
    
            // 保存模糊后的图像
            String outputImagePath = "path/to/save/blurred_image.jpg";
            Imgcodecs.imwrite(outputImagePath, image);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    腐蚀和膨胀

    膨胀被用来增加图像中边缘的大小。首先,我们定义了奇数(5,5)的核矩阵大小。然后使用内核,我们对图像执行膨胀。

    腐蚀与膨胀正好相反。该算法用于减小图像中边缘的大小。首先,我们定义了奇数(5,5)的核矩阵大小。然后使用内核,我们对图像执行腐蚀。

    // 膨胀
    kernel = np.ones((5,5),np.uint8) ## DEFINING KERNEL OF 5x5
    imgDialation = cv2.dilate(imgCanny,kernel,iterations=1) ##DIALATION
    // 腐蚀
    Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3));
    Imgproc.erode(binaryImage, binaryImage, kernel);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    直方图均衡化

    提高图像的对比度,使图像更清晰。

    Imgproc.cvtColor(image, image, Imgproc.COLOR_BGR2GRAY);
    Imgproc.equalizeHist(image, image);
    
    • 1
    • 2

    图像分割

    将图像分割成不同的区域或对象。

    Mat labels = new Mat();
    Mat stats = new Mat();
    Mat centroids = new Mat();
    Imgproc.connectedComponentsWithStats(binaryImage, labels, stats, centroids);
    
    • 1
    • 2
    • 3
    • 4

    模板匹配

    在图像中查找特定模板的位置。

    Mat template = Imgcodecs.imread("path/to/template.jpg");
    Mat result = new Mat();
    Imgproc.matchTemplate(image, template, result, Imgproc.TM_CCOEFF_NORMED);
    
    • 1
    • 2
    • 3

    图像特征提取

    使用特征检测器提取图像中的关键点和描述符。

    MatOfKeyPoint keypoints = new MatOfKeyPoint();
    FeatureDetector detector = FeatureDetector.create(FeatureDetector.SIFT);
    detector.detect(image, keypoints);
    
    • 1
    • 2
    • 3

    图像拟合

    对图像中的几何形状进行拟合,如拟合直线或圆。

    MatOfPoint2f approxCurve = new MatOfPoint2f();
    Imgproc.approxPolyDP(new MatOfPoint2f(contour), approxCurve, epsilon, true);
    
    • 1
    • 2

    图像标注

    在图像上添加文本、线条或形状,以标识或注释图像。

    Scalar color = new Scalar(0, 0, 255); // 红色
    Point startPoint = new Point(10, 10); // 起始点
    Imgproc.putText(image, "Sample Text", startPoint, Core.FONT_HERSHEY_SIMPLEX, 0.5, color, 2);
    
    • 1
    • 2
    • 3

    轮廓检测

    查找并绘制图像中的对象轮廓。

    List<MatOfPoint> contours = new ArrayList<>();
    Imgproc.findContours(binaryImage, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
    Imgproc.drawContours(image, contours, -1, new Scalar(0, 255, 0), 2);
    
    • 1
    • 2
    • 3

    背景减除

    从图像中分离前景对象和背景。

    BackgroundSubtractorMOG2 bgSubtractor = Video.createBackgroundSubtractorMOG2();
    Mat foregroundMask = new Mat();
    bgSubtractor.apply(image, foregroundMask);
    
    • 1
    • 2
    • 3

    图像混合

    将两个图像叠加在一起以创建混合效果。

    Mat image1 = Imgcodecs.imread("path/to/image1.jpg");
    Mat image2 = Imgcodecs.imread("path/to/image2.jpg");
    Mat blendedImage = new Mat();
    Core.addWeighted(image1, 0.7, image2, 0.3, 0, blendedImage);
    
    • 1
    • 2
    • 3
    • 4

    颜色分割

    将图像分割成不同的颜色通道。

    List<Mat> channels = new ArrayList<>();
    Core.split(image, channels);
    
    • 1
    • 2

    图像旋转裁剪

    旋转并裁剪图像以获取感兴趣的区域。

    javaCopy codedouble angle = 30; // 旋转角度
    Point center = new Point(image.cols() / 2, image.rows() / 2);
    Mat rotationMatrix = Imgproc.getRotationMatrix2D(center, angle, 1.0);
    Imgproc.warpAffine(image, image, rotationMatrix, image.size());
    Rect roi = new Rect(x, y, width, height); // 定义感兴趣的区域
    Mat croppedImage = new Mat(image, roi);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在图像上写文字

    import org.opencv.core.Core;
    import org.opencv.core.Mat;
    import org.opencv.core.Point;
    import org.opencv.core.Scalar;
    import org.opencv.imgcodecs.Imgcodecs;
    import org.opencv.imgproc.Imgproc;
    public class WriteTextOnImage {
        public static void main(String[] args) {
            System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
            // 读取图像
            String imagePath = "path/to/your/image.jpg";
            Mat image = Imgcodecs.imread(imagePath);
            if (image.empty()) {
                System.out.println("Could not open or find the image");
                return;
            }
            // 定义文本和位置
            String text = "Hello, OpenCV!";
            Point position = new Point(50, 50); // 文本的左上角位置
            int fontFace = Imgproc.FONT_HERSHEY_SIMPLEX;
            double fontScale = 1.0;
            Scalar color = new Scalar(0, 0, 255); // 文本颜色 (BGR格式)
            int thickness = 2;
            // 在图像上添加文本
            Imgproc.putText(image, text, position, fontFace, fontScale, color, thickness);
            // 保存带有文本的图像
            String outputImagePath = "path/to/save/output_image.jpg";
            Imgcodecs.imwrite(outputImagePath, image);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    检测和裁剪人脸

    人脸检测在人脸识别系统中非常有用。在 OpenCV 中,我们有许多预先训练的 haar 级联分类器可用于不同的任务。以下网址可以查看 OpenCV GitHub 上的分类器列表:https://github.com/opencv/opencv/tree/master/data/haarca
    scades。

    我们使用 haarcascade_frontalface_default.xml 分类器来检测图像中的人脸。它将返回图像的四个坐标(w,h,x,y)。使用这些坐标,我们要在脸上画一个矩形,然后使用相同的坐标,继续裁剪人脸。最后使用 imwrite,把裁剪后的图像保存到目录中。

    import org.opencv.core.Core;
    import org.opencv.core.Mat;
    import org.opencv.core.Rect;
    import org.opencv.core.Scalar;
    import org.opencv.core.Size;
    import org.opencv.imgcodecs.Imgcodecs;
    import org.opencv.imgproc.Imgproc;
    import org.opencv.objdetect.CascadeClassifier;
    public class DetectAndCropFace {
        public static void main(String[] args) {
            System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
            // 加载人脸检测器
            String faceCascadePath = "path/to/haarcascade_frontalface_default.xml";
            CascadeClassifier faceCascade = new CascadeClassifier(faceCascadePath);
            // 读取图像
            String imagePath = "path/to/your/image.jpg";
            Mat image = Imgcodecs.imread(imagePath);
            if (image.empty()) {
                System.out.println("Could not open or find the image");
                return;
            }
            // 转换图像为灰度
            Mat grayImage = new Mat();
            Imgproc.cvtColor(image, grayImage, Imgproc.COLOR_BGR2GRAY);
            Imgproc.equalizeHist(grayImage, grayImage);
            // 检测人脸
            MatOfRect faceDetections = new MatOfRect();
            faceCascade.detectMultiScale(grayImage, faceDetections);
            // 遍历检测到的人脸并裁剪
            for (Rect rect : faceDetections.toArray()) {
                // 裁剪人脸区域
                Mat croppedFace = new Mat(image, rect);
                // 绘制矩形框以标识人脸
                Imgproc.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0), 2);
                // 保存裁剪的人脸图像
                String outputImagePath = "path/to/save/face_" + System.currentTimeMillis() + ".jpg";
                Imgcodecs.imwrite(outputImagePath, croppedFace);
            }
            // 保存带有人脸标识的图像
            String outputImagePath = "path/to/save/output_image.jpg";
            Imgcodecs.imwrite(outputImagePath, image);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    灰度化图像

    图像灰度化是一种常见的预处理步骤,可以将彩色图像转换为灰度图像。

    import org.opencv.core.Mat;
    import org.opencv.highgui.HighGui;
    import org.opencv.imgcodecs.Imgcodecs;
    import org.opencv.imgproc.Imgproc;
    public class Test {
        public static void main(String[] args) {
            // 加载 OpenCV 库
            nu.pattern.OpenCV.loadShared();
            // 加载彩色图像
            Mat colorImage = Imgcodecs.imread("images/_abc.png");
            // 将彩色图像转换为灰度图像
            Mat grayscaleImage = new Mat();
            Imgproc.cvtColor(colorImage, grayscaleImage, Imgproc.COLOR_BGR2GRAY);
            // 显示灰度图像
            HighGui.imshow("Grayscale Image", grayscaleImage);
            HighGui.waitKey();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    二值化

    二值化是一种图像处理技术,将图像转换为只包含两个像素值的图像,通常为黑色和白色(或0和255),以便更容易进行目标检测、图像分割和其他计算机视觉任务。在 OpenCV 中,可以使用不同的阈值方法来进行二值化。

    1. 简单二值化: 简单二值化是根据一个固定的阈值将图像分为黑白两部分。

      import org.opencv.core.Core;
      import org.opencv.core.Mat;
      import org.opencv.imgcodecs.Imgcodecs;
      import org.opencv.imgproc.Imgproc;
      
      public class SimpleThresholdingExample {
          public static void main(String[] args) {
              System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
      
              // 读取图像
              String imagePath = "path/to/your/image.jpg";
              Mat image = Imgcodecs.imread(imagePath);
      
              if (image.empty()) {
                  System.out.println("Could not open or find the image");
                  return;
              }
      
              // 将图像转换为灰度
              Mat grayImage = new Mat();
              Imgproc.cvtColor(image, grayImage, Imgproc.COLOR_BGR2GRAY);
      
              // 应用简单二值化
              Mat binaryImage = new Mat();
              Imgproc.threshold(grayImage, binaryImage, 128, 255, Imgproc.THRESH_BINARY);
      
              // 保存二值化后的图像
              String outputImagePath = "path/to/save/binary_image.jpg";
              Imgcodecs.imwrite(outputImagePath, binaryImage);
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
    2. 自适应二值化: 自适应二值化根据每个像素周围的局部区域自动确定阈值。

      import org.opencv.core.Core;
      import org.opencv.core.Mat;
      import org.opencv.imgcodecs.Imgcodecs;
      import org.opencv.imgproc.Imgproc;
      
      public class AdaptiveThresholdingExample {
          public static void main(String[] args) {
              System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
      
              // 读取图像
              String imagePath = "path/to/your/image.jpg";
              Mat image = Imgcodecs.imread(imagePath);
      
              if (image.empty()) {
                  System.out.println("Could not open or find the image");
                  return;
              }
      
              // 将图像转换为灰度
              Mat grayImage = new Mat();
              Imgproc.cvtColor(image, grayImage, Imgproc.COLOR_BGR2GRAY);
      
              // 应用自适应二值化
              Mat binaryImage = new Mat();
              Imgproc.adaptiveThreshold(grayImage, binaryImage, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 11, 2);
      
              // 保存二值化后的图像
              String outputImagePath = "path/to/save/adaptive_binary_image.jpg";
              Imgcodecs.imwrite(outputImagePath, binaryImage);
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31

    背景去除

    import org.opencv.core.Core;
    import org.opencv.core.Mat;
    import org.opencv.core.Scalar;
    import org.opencv.imgcodecs.Imgcodecs;
    import org.opencv.video.BackgroundSubtractor;
    import org.opencv.video.Video;
    public class RemoveBackground {
        public static void main(String[] args) {
            System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
            // 读取图像
            String imagePath = "path/to/your/image.jpg";
            Mat image = Imgcodecs.imread(imagePath);
    
            if (image.empty()) {
                System.out.println("Could not open or find the image");
                return;
            }
            // 创建背景减除器
            BackgroundSubtractor bgSubtractor = Video.createBackgroundSubtractorMOG2();
            // 去除背景
            Mat fgMask = new Mat();
            bgSubtractor.apply(image, fgMask);
            // 创建结果图像
            Mat resultImage = new Mat();
            image.copyTo(resultImage, fgMask);
            // 保存去除背景后的图像
            String outputImagePath = "path/to/save/output_image.jpg";
            Imgcodecs.imwrite(outputImagePath, resultImage);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    特征点检测

    特征点检测是计算机视觉领域的一项重要任务,用于在图像中检测并描述具有独特属性的关键点,以便在不同图像之间进行匹配、跟踪或对象识别。OpenCV 提供了多种特征点检测算法,其中最常用的是 SIFT 和 ORB。

    1. SIFT 特征点检测

      import org.opencv.core.Core;
      import org.opencv.core.Mat;
      import org.opencv.core.MatOfKeyPoint;
      import org.opencv.features2d.Features2d;
      import org.opencv.features2d.SIFT;
      import org.opencv.imgcodecs.Imgcodecs;
      
      public class SiftFeatureDetection {
          public static void main(String[] args) {
              System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
      
              // 读取图像
              String imagePath = "path/to/your/image.jpg";
              Mat image = Imgcodecs.imread(imagePath);
      
              if (image.empty()) {
                  System.out.println("Could not open or find the image");
                  return;
              }
      
              // 初始化 SIFT 特征检测器
              SIFT sift = SIFT.create();
      
              // 检测图像中的 SIFT 特征点
              MatOfKeyPoint keyPoints = new MatOfKeyPoint();
              sift.detect(image, keyPoints);
      
              // 在图像上绘制特征点
              Mat outputImage = new Mat();
              Features2d.drawKeypoints(image, keyPoints, outputImage);
      
              // 保存带有特征点的图像
              String outputImagePath = "path/to/save/sift_keypoints_image.jpg";
              Imgcodecs.imwrite(outputImagePath, outputImage);
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
    2. ORB 特征点检测

      import org.opencv.core.Core;
      import org.opencv.core.Mat;
      import org.opencv.features2d.Features2d;
      import org.opencv.features2d.ORB;
      import org.opencv.imgcodecs.Imgcodecs;
      
      public class OrbFeatureDetection {
          public static void main(String[] args) {
              System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
      
              // 读取图像
              String imagePath = "path/to/your/image.jpg";
              Mat image = Imgcodecs.imread(imagePath);
      
              if (image.empty()) {
                  System.out.println("Could not open or find the image");
                  return;
              }
      
              // 初始化 ORB 特征检测器
              ORB orb = ORB.create();
      
              // 检测图像中的 ORB 特征点
              MatOfKeyPoint keyPoints = new MatOfKeyPoint();
              orb.detect(image, keyPoints);
      
              // 在图像上绘制特征点
              Mat outputImage = new Mat();
              Features2d.drawKeypoints(image, keyPoints, outputImage);
      
              // 保存带有特征点的图像
              String outputImagePath = "path/to/save/orb_keypoints_image.jpg";
              Imgcodecs.imwrite(outputImagePath, outputImage);
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35

    参考

    • https://www.opencv.org.cn/
      • https://www.opencv.org.cn/forum/forum.php?mod=viewthread&tid=33549
      • https://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/tutorials.html
    • https://www.hhai.cc/thread-3-1-1.html
    • https://gitee.com/songer/java_opencv
    • https://gitee.com/opencv_ai/opencv_tutorial_data
    • https://gitee.com/endlesshh/opencv343_face_recognition
  • 相关阅读:
    pmp是什么意思啊?
    虚幻C+++基础 day2
    【第四部分 | JavaScript 基础】1:JS概述、变量及输入输出
    [ vulhub漏洞复现篇 ] Django SQL注入漏洞复现 CVE-2021-35042
    【LeetCode】2760. 最长奇偶子数组
    流体力学基础——简介
    gpg: keyserver receive failed: Cannot assign requested address
    Rainbow: Combining Improvements in Deep Reinforcement Learning
    Linux系统安全——iptables相关总结
    学习笔记|计数器|Keil软件中 0xFD问题|I/O口配置|STC32G单片机视频开发教程(冲哥)|第十二集:计数器的作用和意义
  • 原文地址:https://blog.csdn.net/abu935009066/article/details/133383609