【Java版本OpenCV】无敌OpenCV越学越爽Java版代码持续更新(环境搭建|核心代码)

特别说明

  1. 本文为B站李超老师的无敌Opencv越学越爽Java版代码(个人学习笔记),原视频为python语言讲解的,纯理论知识可直接看视频,实战代码为对应的Java版本,已经跟完B站所有章节,代码后续找时间补到章节名称下
  2. 个人感觉有些章节可以忽略的在章节下面做了备注,比如各种环境的安装,java可以直接用免安装的方式运行,所以这几节可以不看,节省点时间
  3. 个人感觉最用有的时区域找图,截图桌面图片,再桌面图片里寻找目标图片,拿到目标点的中心坐标,然后就可以利用Robot来实现各种鼠标键盘操作了,另外还有人脸识别,在桌面区域里面找人脸,就是不知道能不能识别出穿越火线里面的人脸,只要能识别到是不是可以用Robot控制鼠标移动到脑袋中间位置,在然后实现爆头▄︻┻┳═一…… ☆(>○<)效果,你们觉得那些功能比较实用,可以留言讨论
  4. B站教程链接https://www.bilibili.com/video/BV14P411D7MH/?spm_id_from=333.337.search-card.all.click&vd_source=ab54f52e92aff1f918ef3cbff7d66562
    在这里插入图片描述

Java版Opencv从入门到入坑

1-2 OpenCV导学

1-3 计算机视觉到底是什么

以上两节看视频介绍,无代码

2-1 Mac下命令方式搭建OpenCV开发环境(加片头)

2-2 Windows下搭建OpenCV开发环境

2-3 Ubuntu下搭建OpenCV开发环境

2-4 Windows下源码方式编译OpenCV

2-5 Windows下C++使用OpenCV库

2-6 如何利用工具高效开发OpenCV

以上章节采免安装方式,所以安装章节可以直接跳过,节约点时间用springboot整合OpenCV(也可以用maven项目或者简单的java项目),主要是引入一个jar包和库文件,jar跨平台,库文件不跨平台,所以要区分windows和linux,至于工具idea就ok.
环境安装可以参考:springboot免安装整合Opencv兼容windows和linux

3-1 明晰课程项目

3-2 如何通过OpenCV创建显示窗口

3-3 如何通过OpenCV加载显示图片

3-4 两招解决OpenCV加载图片问题

实战代码

/**
 * 读取图片并显示
 */
public class P1ReadAndDisplayImage {
    public static void main(String[] args) {
        // 加载Opencv库 不一定要在项目里面,需要绝对路径
        System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
        // 读取图片
        Mat img = Imgcodecs.imread("src/main/resources/img/lenna1.png");
        // 在hello窗口中显示图片
        HighGui.imshow("hello", img);
        // 等待按键 不设置设计会一直等待
        HighGui.waitKey();
        // 销毁所有窗口
        HighGui.destroyAllWindows();
        // 退出系统
        System.exit(0);
    }
}

3-5 如何通过OpenCV保存文件

public class P2SaveImage {
    public static void main(String[] args) {
        // 加载Opencv库 不一定要在项目里面,需要绝对路径
        System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
        // 读取图片
        Mat img = Imgcodecs.imread("src/main/resources/img/lenna1.png");
        // 保存图片 图片格式可以和原图片一致,也可以不一致
        String fileName = "src/main/resources/tmp/lenna1.jpg";
        Imgcodecs.imwrite(fileName, img);
    }
}

3-6 如何利用OpenCV从摄像头采集视频

public class P3CameraStudy {
    public static void main(String[] args) {
        // 加载动态库
        System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
        // 打开默认摄像头(索引为0)
        VideoCapture capture = new VideoCapture(0);
        // 检查摄像头是否成功打开
        if (!capture.isOpened()) {
            System.out.println("无法打开摄像头。");
            return;
        }
        // 从摄像头读取并显示每一帧
        Mat frame = new Mat();
        while (capture.read(frame)) {
            // 显示图片 HighGui用户界面相关
            HighGui.imshow("Camera", frame);
            // 等待3毫秒 也就是每3毫秒从摄像头读取一帧
            int key = HighGui.waitKey(3);
            // 如果输入q 则释放资源
            if (key == 'q' || key == 'Q') {
                // 销毁所有窗口
                HighGui.destroyAllWindows();
                // 释放 VideoCapture 对象
                capture.release();
                System.exit(0);
                break;
            }

        }
        // 销毁所有窗口
        HighGui.destroyAllWindows();
        // 释放 VideoCapture 对象
        capture.release();
        System.exit(0);
    }
}

3-7 如何从多媒体文件中读取视频帧

3-8 如何将视频数据录制成多媒体文件

public class P4VideoStudy {
    public static void main(String[] args) {
        // 加载动态库
        System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
        // 读取本地视频
        VideoCapture capture = new VideoCapture("src/main/resources/video/video.mp4");
        // 获取视频的宽度、高度和帧数
        double width = capture.get(Videoio.CAP_PROP_FRAME_WIDTH);
        double height = capture.get(Videoio.CAP_PROP_FRAME_HEIGHT);
        double frameCount = capture.get(Videoio.CAP_PROP_FRAME_COUNT);
        // 获取视频的帧数和总时长
        double totalSeconds = frameCount / capture.get(Videoio.CAP_PROP_FPS);
        // 计算平均帧率
        double fps = frameCount / totalSeconds;
        // 输出视频信息
        System.out.println("视频宽度: " + width);
        System.out.println("视频高度: " + height);
        System.out.println("视频帧数: " + frameCount);
        System.out.println("总时长: " + totalSeconds);
        System.out.println("平均帧率: " + fps);

        // 定义输出视频文件路径
        String outputFilePath = "src/main/resources/tmp/output_video.mp4";

        // 定义视频属性 width 和 height 不对写不进去
        Size frameSize = new Size(width, height);
        // 创建 VideoWriter 对象
        VideoWriter videoWriter = new VideoWriter(outputFilePath, VideoWriter.fourcc('H', '2', '6', '4'), fps, frameSize, true);

        // 检查视频是否成功打开
        if (!capture.isOpened()) {
            System.out.println("无法打开视频");
            return;
        }
        // 检查 VideoWriter 对象是否成功初始化
        if (!videoWriter.isOpened()) {
            System.out.println("错误:无法打开视频文件以进行写入。");
            return;
        }
        // 从视频读取并显示每一帧
        Mat frame = new Mat();
        while (capture.read(frame)) {
            if (!frame.empty()) {
                videoWriter.write(frame);
            }
            // 显示图片 HighGui用户界面相关
            HighGui.imshow("Video", frame);
            // 输入一次就中断了
            int key = HighGui.waitKey(30);
            System.out.println("key = " + key+"\t" + (char)key);
            if (key == 'q' || key == 'Q') {
                HighGui.destroyAllWindows();
                capture.release();
                videoWriter.release();
                System.exit(0);
                break;
            }
        }
        HighGui.destroyAllWindows();
        capture.release();
        videoWriter.release();
        System.exit(0);
    }
}

3-9 代码优化

3-10 OpenCV控制鼠标

3-11 OpenCV中的TrackBar控件

3-12 实战TrackBar的使用

以上章节感觉没必要看,可直接忽略

4-1 RGB与BGR【OpenCV的色彩空间】

4-2 HSV与HSL【OpenCV的色彩空间】

4-3 实战OpenCV色彩空间转换

纯理论,可直接看视频

4-4 图像操作的基石Numpy【基础操作】

4-5 Numpy基本操作之矩阵的检索与赋值

4-6 Numpy基本操作三-ROI

以上三节直接忽略,Java提供了ROI的api(ROI 感兴趣的区域,就是一张图片中自己比较关心的那部分)

4-8 OpenCV的重要结构体Mat

4-9 Mat的深拷贝与浅拷贝

插播一个显示图片的工具类,解决图片显示在一起的位置,效果图片在屏幕上排列

public static void show(LinkedHashMap<String, Mat> mats) {
    // 获取默认工具包
    Toolkit toolkit = Toolkit.getDefaultToolkit();
    // 获取屏幕的尺寸
    Dimension screenSize = toolkit.getScreenSize();
    // 输出屏幕宽度和高度
    int i = 0;
    int x = 0;
    int y = 0;
    int xSpacing = 10;
    int ySpacing = 40;
    for (Map.Entry<String, Mat> entry : mats.entrySet()) {
        Mat mat = entry.getValue();
        String winName = entry.getKey();
        System.out.println("winName = " + winName);
        HighGui.imshow(winName, mat);
        if (i > 0) {
            x += (mat.cols() + xSpacing);
            if (x + mat.cols() > screenSize.width) {
                x = 0;
                y += (mat.rows() + ySpacing);
            }
        }
        HighGui.moveWindow(winName, x, y);
        i++;
    }
    HighGui.waitKey();
}
public class P490MatCopyStudy {
    public static void main(String[] args) {
        // 加载动态库
        System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());

        // 读取图片
        Mat image = Imgcodecs.imread("src/main/resources/img/lenna1.png");
        //  是深拷贝
        Mat clone = image.clone();
        // 深拷贝
        Mat copyTo = new Mat();
        image.copyTo(copyTo);

        // 在image上上绘制文本
        // 文本的位置
        Point textPosition = new Point(50, 50);
        String text = "Hello, OpenCV!";
        // 白色,字体大小为 1.0,线宽为 2
        Imgproc.putText(image, text, textPosition, Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 255), 2);
        LinkedHashMap<String, Mat> images = new LinkedHashMap<>();
        images.put("原图", image);
        images.put("clone", clone);
        images.put("copyTo", copyTo);
        OpenCVUtil.show(images);
        HighGui.destroyAllWindows();
    }
}

说明:通过以上代码可以看出,在Java中clone和copyTo均为深拷贝

image-20240317202552226

4-11 图像的多种属性

4-12 通道的分割与合并

public class P412MatSplitAndMerge {
    public static void main(String[] args) {
        // 加载动态库
        System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
        // 读取原图
        Mat image = Imgcodecs.imread("src/main/resources/img/lenna1.png");
        // 显示图片
        HighGui.imshow("原图", image);
        // 分离通道
        List<Mat> channels = new ArrayList<>();
        Core.split(image, channels);
        for (int i = 0; i < channels.size(); i++) {
            Mat mat = channels.get(i);
            // 分离出来的3个通道均为单通道,故显示出来都是黑白图片
            HighGui.imshow("通道" + i, mat);
        }
        List<Mat> mergeChannels = new ArrayList<>();
        mergeChannels.add(channels.get(0));
        mergeChannels.add(channels.get(1));
        mergeChannels.add(channels.get(2));
        Mat newMat = new Mat();
        // 合并通道
        Core.merge(mergeChannels,newMat);
        HighGui.imshow("合并后的图像", newMat);
        HighGui.waitKey();
        HighGui.destroyAllWindows();
        System.exit(0);
    }
}

绘制基本图形

5-1 OpenCV绘制直线

5-2 OpenCV椭圆的绘制

5-3 OpenCV椭圆的绘制

5-4 OpenCV绘制多边形

5-5 OpenCV绘制文本5-6 OpenCV大作业-实现鼠标绘制基本图形

5-7 OpenCV基本图形绘制小结

代码实战

public class P500BasicShapeDrawingExample {
    public static void main(String[] args) {
        // 加载动态库
        System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
        // 创建一个黑色背景的图像
        Mat image = new Mat(400, 600, CvType.CV_8UC3, new Scalar(0, 0, 0)); // 400x600 大小,3 通道的黑色图像

        // 在图像上绘制基本图形
        Point center = new Point(300, 200); // 圆心坐标
        Scalar color = new Scalar(0, 255, 0); // 颜色 (BGR 格式)

        // 绘制圆
        Imgproc.circle(image, center, 100, color, 2); // 中心为 (300, 200),半径为 100,边界宽度为 2,绿色

        // 绘制矩形
        Point topLeft = new Point(100, 100); // 左上角坐标
        Point bottomRight = new Point(500, 300); // 右下角坐标
        Imgproc.rectangle(image, topLeft, bottomRight, new Scalar(0, 0, 255), 3); // 左上角 (100, 100),右下角 (500, 300),红色,边界宽度为 3

        // 绘制直线
        Point start = new Point(50, 50); // 起始点坐标
        Point end = new Point(550, 350); // 结束点坐标
        Imgproc.line(image, start, end, new Scalar(255, 0, 0), 1); // 蓝色,线宽为 1

        // 在图像上绘制文本
        Point textPosition = new Point(50, 50); // 文本的位置
        String text = "Hello, OpenCV!"; // 要绘制的文本
        Imgproc.putText(image, text, textPosition, Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 255), 2); // 白色,字体大小为 1.0,线宽为 2


        HighGui.imshow("基本图形的绘制", image);
        HighGui.waitKey(0);
        HighGui.destroyAllWindows();
        System.exit(0);

    }
}

效果

image-20240307162224661

6-1 图像的加法运算

6-2 图像的减法运算

public class P620ImageArithmeticExample {
    public static void main(String[] args) {
        // // 加载动态库
        System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
        // 加载两个图像
        String imagePath1 = "src/main/resources/img/lenna1.png";
        Mat image1 = Imgcodecs.imread(imagePath1);
        // 检查图像是否成功加载
        if (image1.empty()) {
            System.out.println("Error: Couldn't load images.");
            return;
        }
        HighGui.imshow("原图", image1);
        // 创建与图像1尺寸相同的图像2,每个像素值为100
        Mat image2 = new Mat(image1.size(), image1.type(), new Scalar(100));

        // 创建一个与图像1尺寸和类型相同的空白图像,用于存储结果
        Mat result4add = new Mat(image1.size(), image1.type());
        Mat result4subtract = new Mat(image1.size(), image1.type());
        // 加法运算
        Core.add(image1, image2, result4add);
        HighGui.imshow("图像相加", result4add);
        // 减法运算
        Core.subtract(image1, image2, result4subtract);
        HighGui.imshow("图像相减", result4subtract);
        HighGui.waitKey(0);
        HighGui.destroyAllWindows();
        System.exit(0);
    }
}

image-20240307163214291

图像的明暗变化(图像加减乘除混合运算)

public class P621DarknessAdjustmentExample {
    public static void main(String[] args) {
        // 加载动态库
        System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
        // 加载两个图像
        Mat image1 = Imgcodecs.imread("src/main/resources/img/lenna1.png");
        // 检查图像是否成功加载
        if (image1.empty()) {
            System.out.println("Error: Couldn't load images.");
            return;
        }
        HighGui.imshow("原图像", image1);
        // 定义暗度调整系数(在 0 到 1 之间)
        double darknessFactor = 0.5; // 减少 50%
        // 将图像1的每个像素值乘以暗度调整系数
        // rtype:转换后的目标数据类型。如果值为 -1,则表示使用与源 Mat 对象相同的数据类型。
        // 原像素值*alpha+beta
        Mat clone = image1.clone();
        clone.convertTo(clone, -1, darknessFactor, 0);
        HighGui.imshow("明暗变化后", clone);
        HighGui.waitKey(0);
        HighGui.destroyAllWindows();
        System.exit(0);
    }
}

image-20240307164043489

6-3 图像的溶合

public class P630ImageFusionExample {
    public static void main(String[] args) {
        // 加载动态库
        System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());

        // 读取图像1和图像2
        Mat image1 = Imgcodecs.imread("src/main/resources/img/dog.jpg");
        Mat image2 = Imgcodecs.imread("src/main/resources/img/background.jpg");
        // 融合要求两张图片具有相同尺寸
        Size size = getSize(image1, image2);
        // 图像融合
        Mat blendedImage = blendImages(resizeImages(image1, size), resizeImages(image2, size));
        // 显示融合后的图像
        HighGui.imshow("Blended Image", blendedImage);
        HighGui.waitKey(0);
        HighGui.destroyAllWindows();
        System.exit(0);
    }

    private static Size getSize(Mat image1, Mat image2) {
        int minWidth = Math.min(image1.width(), image2.width());
        int minHeight = Math.min(image1.height(), image2.height());
        return new Size(minWidth, minHeight);
    }

    // 将图像调整为size大小
    private static Mat resizeImages(Mat image, Size size) {
        Mat mat = new Mat(size, image.type());
        Imgproc.resize(image, mat, size);
        return mat;
    }

    // 图像融合
    private static Mat blendImages(Mat image1, Mat image2) {
        double alpha = 0.9; // 调整融合的权重
        Mat blendedImage = new Mat();
        Core.addWeighted(image1, alpha, image2, 1 - alpha, 0, blendedImage);
        return blendedImage;
    }
}

原图1

image-20240307165538704

原图2

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

融合效果

image-20240307165455433

6-4 OpenCV位运算-非操作

public class P640ImageNegationExample {
    public static void main(String[] args) {
        // 加载动态库
        System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
        // 读取图像
        Mat image = Imgcodecs.imread("src/main/resources/img/lenna1.png");

        HighGui.imshow("原图", image);
        Mat mat = new Mat();
        Core.bitwise_not(image, mat);

        // 显示融合后的图像
        HighGui.imshow("图像的非运算", mat);
        HighGui.waitKey(0);
        HighGui.destroyAllWindows();
        System.exit(0);
    }
}

image-20240307170138324

6-5 OpenCV位操作-与运算

6-6 OpenCV位操作-或与异或

6-7 大作业-为图像添加水印

public class P670AddLogo {
    public static void main(String[] args) {
        // 加载动态库
        System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
        // 1. 引入图片
        Mat background = Imgcodecs.imread("src/main/resources/img/background.jpg");
        // 2. 制作logo
        Mat logo = new Mat(200, 200, CvType.CV_8UC3, new Scalar(0, 0, 0));
        Mat mask = new Mat(200, 200, CvType.CV_8UC1, new Scalar(0, 0, 0));
        Point topLeft = new Point(20, 20);
        Point bottomRight = new Point(120, 120);
        Imgproc.rectangle(logo, topLeft, bottomRight, new Scalar(0, 0, 255), 2);
        Imgproc.rectangle(mask, topLeft, bottomRight, new Scalar(255, 255, 255), 2);
        topLeft = new Point(80, 80);
        bottomRight = new Point(180, 180);
        Imgproc.rectangle(logo, topLeft, bottomRight, new Scalar(0, 255, 0), 2);
        Imgproc.rectangle(mask, topLeft, bottomRight, new Scalar(255, 255, 255), 2);
        Mat m = new Mat();
        Core.bitwise_not(mask, m);
        HighGui.imshow("logo", logo);
        HighGui.imshow("mask", mask);
        HighGui.imshow("m", m);

        // 3. 计算添加位置,将添加位置变黑
        Mat roi = new Mat(background, new Rect(0, 0, 200, 200));
        HighGui.imshow("roi", roi);
        Mat tmp = new Mat();
        Core.bitwise_and(roi, roi, tmp, m);
        HighGui.imshow("tmp", tmp);
        Mat dst = new Mat();
        Core.add(tmp, logo, dst);
        HighGui.imshow("dst", dst);
        // 4.利用add,将图片和logo叠加到一起

        Mat submat = background.submat(new Rect(0, 0, 200, 200));
        dst.copyTo(submat);
        HighGui.imshow("background", background);
        HighGui.waitKey(0);
        HighGui.destroyAllWindows();
        System.exit(0);
    }
}

image-20240307170903446

7-1 图像的放大与缩小

public class P710Scale {
    public static void main(String[] args) {
        // 加载动态库
        System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());

        // 读取图像
        Mat originalImage = Imgcodecs.imread("src/main/resources/img/idea.png");

        // 定义缩放后的图像大小
        Size newSize = new Size(originalImage.width() * 5, originalImage.height() * 5);

        // 缩放图像(使用双立方插值)
        Mat resizedImage = new Mat();
        Imgproc.resize(originalImage, resizedImage, newSize, 0, 0, Imgproc.INTER_AREA);

        // 显示原始图像和缩放后的图像
        HighGui.imshow("Original Image", originalImage);
        HighGui.imshow("Resized Image", resizedImage);
        HighGui.waitKey(0);
        HighGui.destroyAllWindows();
        System.exit(0);
    }
}

image-20240317203337386

说明:第一张是原图,第二张是放大5倍的图,放大之后图像会模糊

7-2 图像的翻转

7-3 图像的旋转

/**
 * 图像的反转
 * 0:沿X轴翻转(垂直翻转)
 * 1:沿Y轴翻转(水平翻转)
 * -1:同时沿X轴和Y轴翻转
 */
public class P730ImageFlipExample {

    public static void main(String[] args) {
        // 加载动态库
        System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
        // 读取图像
        Mat originalImage = Imgcodecs.imread("src/main/resources/img/lenna1.png");
        // 沿X轴翻转(垂直翻转)
        Mat dstX = new Mat();
        Core.flip(originalImage, dstX, 0);
        // 沿Y轴翻转(水平翻转)
        Mat dstY = new Mat();
        Core.flip(originalImage, dstY, 1);
        Mat dstXY = new Mat();
        Core.flip(originalImage, dstXY, -1);

        LinkedHashMap<String, Mat> images = new LinkedHashMap<>();
        images.put("原图", originalImage);
        images.put("沿着X轴翻转", dstX);
        images.put("沿着Y轴翻转", dstY);
        images.put("同时沿着XY轴翻转", dstXY);
        OpenCVUtil.show(images);
        HighGui.destroyAllWindows();
        System.exit(0);
    }
}

效果图

image-20240317210827542

7-4 仿射变换之图像平移

7-5 仿射变换之获取变换矩阵

7-6 仿射变换之变换矩阵之二

/**
 * 仿射变幻
 */
public class P760ImageRotateExample {

    public static void main(String[] args) {
        // 加载动态库
        System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
        // 读取图像
        Mat originalImage = Imgcodecs.imread("src/main/resources/img/lenna1.png");

        // 定义旋转角度(逆时针)
        double angle = 45.0;

        // 获取图像中心点
        Point center = new Point(originalImage.cols() / 2, originalImage.rows() / 2);

        // 计算旋转矩阵
        Mat rotationMatrix = Imgproc.getRotationMatrix2D(center, angle, 1.0);

        // 执行旋转变换
        Mat rotatedImage = new Mat();
        Imgproc.warpAffine(originalImage, rotatedImage, rotationMatrix, new Size(originalImage.cols(), originalImage.rows()));

        // 显示原始图像和旋转后的图像
        LinkedHashMap<String, Mat> images = new LinkedHashMap<>();
        images.put("原图", originalImage);
        images.put("逆时针旋转45°", rotatedImage);
        OpenCVUtil.show(images);
        HighGui.destroyAllWindows();
        System.exit(0);
    }
}

image-20240317211351115

7-7 OpenCV透视变换

8-1 图像滤波

OpenCV提供了许多不同类型的滤波器,可以用于图像处理的各种任务。以下是一些常用的滤波器类型:

  1. 低通滤波:去噪

    • 均值滤波器(Mean Filter):用于平滑图像并减少噪声。它计算像素周围区域的平均值,并用该平均值替换中心像素的值。
    • 高斯滤波器(Gaussian Filter):也用于平滑图像并减少噪声,但相比均值滤波器,它更加平滑。它计算像素周围区域的加权平均值,权重由高斯函数确定。
    • 中值滤波器(Median Filter):用于去除椒盐噪声等斑点噪声。它将像素周围区域的值排序,并用中值替换中心像素的值。
    • 双边滤波器(Bilateral Filter):用于平滑图像并保持边缘清晰。它考虑了像素之间的空间距离和像素值之间的相似性,以确定滤波器的权重。
  2. 高通滤波:检测边缘

    • Sobel(索贝尔)滤波器:用于边缘检测。它使用两个3x3的卷积核,分别计算图像的水平和垂直方向的梯度。
    • Laplacian(拉普拉斯)滤波器:也用于边缘检测。它计算图像的二阶导数,并可以提取出图像中的边缘。

8-2 卷积相关概念

8-3 实战图像卷积

8-4 方盒滤波与均值滤波

8-5 高斯滤波

8-6 中值滤波

8-7 双边滤波

8-8 高通滤波-索贝尔算子

8-9 高通滤波-沙尔算子

8-10 高通滤波-拉普拉斯算子

8-11 边缘检测Canny

9-1 形态学概述

9-2 图像全局二值化

9-3 阈值类型

9-4 自适应阈值二值化

9-5 OpenCV腐蚀

9-6 获取形态学卷积核

9-7 OpenCV膨胀

9-8 开运算

9-9 闭运算

9-10 形态学梯度

9-11 顶帽运算

9-12 黑帽操作

10-1 什么是图像轮廓

10-2 查找轮廓

10-3 绘制轮廓

10-4 轮廓的面积与周长

10-5 多边形逼近与凸包

10-6 外接矩形

10-7 项目总览【车辆统计】

10-8 视频加载【车辆统计】

10-9 形态学处理【车辆统计】

10-10 去背景【车辆统计】

10-11 逻辑处理【车辆统计】

10-12 显示信息【车辆统计】

11-1 特征检测的基本概念

11-2 Harris角点检测

11-3 Shi-Tomasi角点检测

11-4 SIFT关键点检测

11-5 SIFT计算描述子

11-6 SURF特征检测

11-7 OBR特征检测

11-8 暴力特征匹配

11-9 FLANN特征匹配

11-10 实战flann特征匹配

11-11 图像查找

11-12 大作业-图像拼接基础知识

11-13 大作业-图像拼接(一)

  • 72
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值