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

2024-06-11 1176阅读

特别说明

  1. 本文为B站李超老师的无敌Opencv越学越爽Java版代码(个人学习笔记),原视频为python语言讲解的,纯理论知识可直接看视频,实战代码为对应的Java版本,已经跟完B站所有章节,代码后续找时间补到章节名称下
  2. 个人感觉有些章节可以忽略的在章节下面做了备注,比如各种环境的安装,java可以直接用免安装的方式运行,所以这几节可以不看,节省点时间
  3. 个人感觉最用有的时区域找图,截图桌面图片,再桌面图片里寻找目标图片,拿到目标点的中心坐标,然后就可以利用Robot来实现各种鼠标键盘操作了,另外还有人脸识别,在桌面区域里面找人脸,就是不知道能不能识别出穿越火线里面的人脸,只要能识别到是不是可以用Robot控制鼠标移动到脑袋中间位置,在然后实现爆头▄︻┻┳═一…… ☆(>○ 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); } } 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); } } 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); } } 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); } } // 获取默认工具包 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 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 images = new LinkedHashMap();
            images.put("原图", image);
            images.put("clone", clone);
            images.put("copyTo", copyTo);
            OpenCVUtil.show(images);
            HighGui.destroyAllWindows();
        }
    }
    

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

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

    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 channels = new ArrayList();
            Core.split(image, channels);
            for (int i = 0; i  
    

    绘制基本图形

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

    效果

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

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

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

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

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

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

    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

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

    原图2

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

    融合效果

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

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

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

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

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

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

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

    说明:第一张是原图,第二张是放大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 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);
        }
    }
    

    效果图

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

    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 images = new LinkedHashMap();
            images.put("原图", originalImage);
            images.put("逆时针旋转45°", rotatedImage);
            OpenCVUtil.show(images);
            HighGui.destroyAllWindows();
            System.exit(0);
        }
    }
    

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

    7-7 OpenCV透视变换

    8-1 图像滤波

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

    1. 低通滤波:去噪

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

        • 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 大作业-图像拼接(一)

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]