C# OpenCvSharp Demo - 棋盘格相机标定

news2024/11/17 3:26:41

C# OpenCvSharp Demo - 棋盘格相机标定

目录

效果

项目

代码

下载


效果

项目

代码

using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
using System.Windows.Forms;

namespace OpenCvSharp_Demo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string startupPath;
        string image_path;

        Stopwatch stopwatch = new Stopwatch();

        Mat image;
        Mat result_image;

        //棋盘格的宽度和高度
        int BoardSize_Width = 9;
        int BoardSize_Height = 6;
        OpenCvSharp.Size BoardSize;

        //每个方格的宽度
        private  int SquareSize = 50;
        private  int winSize = 11;

        StringBuilder sb=new StringBuilder();

        private void Form1_Load(object sender, EventArgs e)
        {
            startupPath = System.Windows.Forms.Application.StartupPath;

            BoardSize = new OpenCvSharp.Size(BoardSize_Width, BoardSize_Height);

            image_path = "1.jpg";
            pictureBox1.Image = new Bitmap(image_path);
            image = new Mat(image_path);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            if (ofd.ShowDialog() != DialogResult.OK) return;

            pictureBox1.Image = null;
            pictureBox2.Image = null;
            textBox1.Text = "";

            image_path = ofd.FileName;
            pictureBox1.Image = new Bitmap(image_path);
            image = new Mat(image_path);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            stopwatch.Restart();
            sb.Clear();

            result_image = image.Clone();

            // 存储每个图像的棋盘角点
            List<Point2f[]> imagesPoints = new List<Point2f[]>();

            // 相机内参矩阵和畸变系数
            Mat cameraMatrix = new Mat(), distCoeffs = new Mat();

            // 图像的尺寸
            OpenCvSharp.Size imageSize = new OpenCvSharp.Size();
            bool found = false;

            // 读取图像
            Mat view = new Mat(image_path);
            Mat p = null;

            if (!view.Empty())
            {
                imageSize = view.Size();
                Point2f[] pointBuf;

                // 查找棋盘角点
                found = Cv2.FindChessboardCorners(view, BoardSize, out pointBuf, ChessboardFlags.AdaptiveThresh | ChessboardFlags.NormalizeImage);

                if (found)
                {
                    // 灰度化
                    Mat viewGray = new Mat();
                    Cv2.CvtColor(view, viewGray, ColorConversionCodes.BGR2GRAY);

                    // 亚像素精确化
                    Cv2.CornerSubPix(viewGray, pointBuf, new OpenCvSharp.Size(winSize, winSize), new OpenCvSharp.Size(-1, -1), new TermCriteria(CriteriaTypes.Eps | CriteriaTypes.Count, 30, 0.0001));

                    // 存储角点坐标
                    imagesPoints.Add(pointBuf);
                    p = Mat.FromArray<Point2f>(pointBuf);

                    // 在图像上绘制角点
                    Cv2.DrawChessboardCorners(view, BoardSize, pointBuf, found);
                    Mat temp = view.Clone();
                    Cv2.ImShow("Image View", view);
                }
            }

            Mat[] rvecs = new Mat[0];
            Mat[] tvecs = new Mat[0];

            // 运行相机标定
            RunCalibration(1, imageSize, out cameraMatrix, out distCoeffs, new Mat[] { p }, out rvecs, out tvecs, out double totalAvgErr);

            // 相机矩阵、畸变系数和平均误差
            sb.AppendLine(string.Format("相机矩阵:\n{0}", Cv2.Format(cameraMatrix) + "\n"));
            sb.AppendLine(string.Format("畸变系数:\n{0}", Cv2.Format(distCoeffs) + "\n"));
            sb.AppendLine(string.Format("平均误差:\n{0}", totalAvgErr + "\n"));

            // 畸变校正
            Mat map1 = new Mat();
            Mat map2 = new Mat();
            Mat newCameraMatrix = Cv2.GetOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, out Rect roi);
            Cv2.InitUndistortRectifyMap(cameraMatrix, distCoeffs, new Mat(), newCameraMatrix, imageSize, MatType.CV_16SC2, map1, map2);

            // 显示校正后的图像
            Mat temp2 = Cv2.ImRead(image_path, ImreadModes.Color);
            Mat rview = new Mat();

            // 校正
            Cv2.Remap(temp2, rview, map1, map2, InterpolationFlags.Linear);

            double costTime = stopwatch.Elapsed.TotalMilliseconds;

            sb.AppendLine( $"\r\n耗时:{costTime:F2}ms");
            textBox1.Text = sb.ToString();
            pictureBox2.Image = new Bitmap(rview.ToMemoryStream());

        }

        // 运行相机标定
        private void RunCalibration(int imagesCount, OpenCvSharp.Size imageSize, out Mat cameraMatrix, out Mat distCoeffs, Mat[] imagePoints, out Mat[] rvecs, out Mat[] tvecs, out double totalAvgErr)
        {
            // 初始化相机矩阵和畸变系数
            cameraMatrix = Mat.Eye(new OpenCvSharp.Size(3, 3), MatType.CV_64F);
            distCoeffs = Mat.Zeros(new OpenCvSharp.Size(8, 1), MatType.CV_64F);

            // 计算棋盘角点的世界坐标
            Mat[] objectPoints = CalcBoardCornerPositions(BoardSize, SquareSize, imagesCount);

            // 进行相机标定
            double rms = Cv2.CalibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, out rvecs, out tvecs, CalibrationFlags.None);

            // 检查相机矩阵和畸变系数的范围
            bool ok = Cv2.CheckRange(InputArray.Create(cameraMatrix)) && Cv2.CheckRange(InputArray.Create(distCoeffs));

            // 计算重投影误差
            totalAvgErr = ComputeReprojectionErrors(objectPoints, imagePoints, rvecs, tvecs, cameraMatrix, distCoeffs);
        }

        // 计算棋盘角点的世界坐标
        private Mat[] CalcBoardCornerPositions(OpenCvSharp.Size BoardSize, float SquareSize, int imagesCount)
        {
            Mat[] corners = new Mat[imagesCount];
            // 遍历每张图片
            for (int k = 0; k < imagesCount; k++)
            {
                Point3f[] p = new Point3f[BoardSize.Height * BoardSize.Width];

                for (int i = 0; i < BoardSize.Height; i++)
                {
                    for (int j = 0; j < BoardSize.Width; j++)
                    {
                        // 计算每个格子的三维坐标并储存在一维数组 p 中
                        p[i * BoardSize.Width + j] = new Point3f(j * SquareSize, i * SquareSize, 0);
                    }
                }
                // 将三维坐标转换成 Mat 类型并存储再 corners 数组中
                corners[k] = Mat.FromArray<Point3f>(p);
            }
            return corners;
        }

        // 计算重投影误差
        private double ComputeReprojectionErrors(Mat[] objectPoints, Mat[] imagePoints, Mat[] rvecs, Mat[] tvecs, Mat cameraMatrix, Mat distCoeffs)
        {
            Mat imagePoints2 = new Mat();
            int totalPoints = 0;
            double totalErr = 0, err;

            for (int i = 0; i < objectPoints.Length; ++i)
            {
                Cv2.ProjectPoints(objectPoints[i], rvecs[i], tvecs[i], cameraMatrix, distCoeffs, imagePoints2);

                err = Cv2.Norm(imagePoints[i], imagePoints2, NormTypes.L2);

                int n = objectPoints[i].Width * objectPoints[i].Height;
                totalErr += err * err;
                totalPoints += n;
            }

            return Math.Sqrt(totalErr / totalPoints);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (pictureBox2.Image == null)
            {
                return;
            }
            Bitmap output = new Bitmap(pictureBox2.Image);
            var sdf = new SaveFileDialog();
            sdf.Title = "保存";
            sdf.Filter = "Images (*.jpg)|*.jpg|Images (*.png)|*.png|Images (*.bmp)|*.bmp|Images (*.emf)|*.emf|Images (*.exif)|*.exif|Images (*.gif)|*.gif|Images (*.ico)|*.ico|Images (*.tiff)|*.tiff|Images (*.wmf)|*.wmf";
            if (sdf.ShowDialog() == DialogResult.OK)
            {
                switch (sdf.FilterIndex)
                {
                    case 1:
                        {
                            output.Save(sdf.FileName, ImageFormat.Jpeg);
                            break;
                        }
                    case 2:
                        {
                            output.Save(sdf.FileName, ImageFormat.Png);
                            break;
                        }
                    case 3:
                        {
                            output.Save(sdf.FileName, ImageFormat.Bmp);
                            break;
                        }
                    case 4:
                        {
                            output.Save(sdf.FileName, ImageFormat.Emf);
                            break;
                        }
                    case 5:
                        {
                            output.Save(sdf.FileName, ImageFormat.Exif);
                            break;
                        }
                    case 6:
                        {
                            output.Save(sdf.FileName, ImageFormat.Gif);
                            break;
                        }
                    case 7:
                        {
                            output.Save(sdf.FileName, ImageFormat.Icon);
                            break;
                        }
                    case 8:
                        {
                            output.Save(sdf.FileName, ImageFormat.Tiff);
                            break;
                        }
                    case 9:
                        {
                            output.Save(sdf.FileName, ImageFormat.Wmf);
                            break;
                        }
                }
                MessageBox.Show("保存成功,位置:" + sdf.FileName);
            }
        }

    }
}

using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
using System.Windows.Forms;

namespace OpenCvSharp_Demo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string startupPath;
        string image_path;

        Stopwatch stopwatch = new Stopwatch();

        Mat image;
        Mat result_image;

        //棋盘格的宽度和高度
        int BoardSize_Width = 9;
        int BoardSize_Height = 6;
        OpenCvSharp.Size BoardSize;

        //每个方格的宽度
        private  int SquareSize = 50;
        private  int winSize = 11;

        StringBuilder sb=new StringBuilder();

        private void Form1_Load(object sender, EventArgs e)
        {
            startupPath = System.Windows.Forms.Application.StartupPath;

            BoardSize = new OpenCvSharp.Size(BoardSize_Width, BoardSize_Height);

            image_path = "1.jpg";
            pictureBox1.Image = new Bitmap(image_path);
            image = new Mat(image_path);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            if (ofd.ShowDialog() != DialogResult.OK) return;

            pictureBox1.Image = null;
            pictureBox2.Image = null;
            textBox1.Text = "";

            image_path = ofd.FileName;
            pictureBox1.Image = new Bitmap(image_path);
            image = new Mat(image_path);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            stopwatch.Restart();
            sb.Clear();

            result_image = image.Clone();

            // 存储每个图像的棋盘角点
            List<Point2f[]> imagesPoints = new List<Point2f[]>();

            // 相机内参矩阵和畸变系数
            Mat cameraMatrix = new Mat(), distCoeffs = new Mat();

            // 图像的尺寸
            OpenCvSharp.Size imageSize = new OpenCvSharp.Size();
            bool found = false;

            // 读取图像
            Mat view = new Mat(image_path);
            Mat p = null;

            if (!view.Empty())
            {
                imageSize = view.Size();
                Point2f[] pointBuf;

                // 查找棋盘角点
                found = Cv2.FindChessboardCorners(view, BoardSize, out pointBuf, ChessboardFlags.AdaptiveThresh | ChessboardFlags.NormalizeImage);

                if (found)
                {
                    // 灰度化
                    Mat viewGray = new Mat();
                    Cv2.CvtColor(view, viewGray, ColorConversionCodes.BGR2GRAY);

                    // 亚像素精确化
                    Cv2.CornerSubPix(viewGray, pointBuf, new OpenCvSharp.Size(winSize, winSize), new OpenCvSharp.Size(-1, -1), new TermCriteria(CriteriaTypes.Eps | CriteriaTypes.Count, 30, 0.0001));

                    // 存储角点坐标
                    imagesPoints.Add(pointBuf);
                    p = Mat.FromArray<Point2f>(pointBuf);

                    // 在图像上绘制角点
                    Cv2.DrawChessboardCorners(view, BoardSize, pointBuf, found);
                    Mat temp = view.Clone();
                    Cv2.ImShow("Image View", view);
                }
            }

            Mat[] rvecs = new Mat[0];
            Mat[] tvecs = new Mat[0];

            // 运行相机标定
            RunCalibration(1, imageSize, out cameraMatrix, out distCoeffs, new Mat[] { p }, out rvecs, out tvecs, out double totalAvgErr);

            // 相机矩阵、畸变系数和平均误差
            sb.AppendLine(string.Format("相机矩阵:\n{0}", Cv2.Format(cameraMatrix) + "\n"));
            sb.AppendLine(string.Format("畸变系数:\n{0}", Cv2.Format(distCoeffs) + "\n"));
            sb.AppendLine(string.Format("平均误差:\n{0}", totalAvgErr + "\n"));

            // 畸变校正
            Mat map1 = new Mat();
            Mat map2 = new Mat();
            Mat newCameraMatrix = Cv2.GetOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, out Rect roi);
            Cv2.InitUndistortRectifyMap(cameraMatrix, distCoeffs, new Mat(), newCameraMatrix, imageSize, MatType.CV_16SC2, map1, map2);

            // 显示校正后的图像
            Mat temp2 = Cv2.ImRead(image_path, ImreadModes.Color);
            Mat rview = new Mat();

            // 校正
            Cv2.Remap(temp2, rview, map1, map2, InterpolationFlags.Linear);

            double costTime = stopwatch.Elapsed.TotalMilliseconds;

            sb.AppendLine( $"\r\n耗时:{costTime:F2}ms");
            textBox1.Text = sb.ToString();
            pictureBox2.Image = new Bitmap(rview.ToMemoryStream());

        }

        // 运行相机标定
        private void RunCalibration(int imagesCount, OpenCvSharp.Size imageSize, out Mat cameraMatrix, out Mat distCoeffs, Mat[] imagePoints, out Mat[] rvecs, out Mat[] tvecs, out double totalAvgErr)
        {
            // 初始化相机矩阵和畸变系数
            cameraMatrix = Mat.Eye(new OpenCvSharp.Size(3, 3), MatType.CV_64F);
            distCoeffs = Mat.Zeros(new OpenCvSharp.Size(8, 1), MatType.CV_64F);

            // 计算棋盘角点的世界坐标
            Mat[] objectPoints = CalcBoardCornerPositions(BoardSize, SquareSize, imagesCount);

            // 进行相机标定
            double rms = Cv2.CalibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, out rvecs, out tvecs, CalibrationFlags.None);

            // 检查相机矩阵和畸变系数的范围
            bool ok = Cv2.CheckRange(InputArray.Create(cameraMatrix)) && Cv2.CheckRange(InputArray.Create(distCoeffs));

            // 计算重投影误差
            totalAvgErr = ComputeReprojectionErrors(objectPoints, imagePoints, rvecs, tvecs, cameraMatrix, distCoeffs);
        }

        // 计算棋盘角点的世界坐标
        private Mat[] CalcBoardCornerPositions(OpenCvSharp.Size BoardSize, float SquareSize, int imagesCount)
        {
            Mat[] corners = new Mat[imagesCount];
            // 遍历每张图片
            for (int k = 0; k < imagesCount; k++)
            {
                Point3f[] p = new Point3f[BoardSize.Height * BoardSize.Width];

                for (int i = 0; i < BoardSize.Height; i++)
                {
                    for (int j = 0; j < BoardSize.Width; j++)
                    {
                        // 计算每个格子的三维坐标并储存在一维数组 p 中
                        p[i * BoardSize.Width + j] = new Point3f(j * SquareSize, i * SquareSize, 0);
                    }
                }
                // 将三维坐标转换成 Mat 类型并存储再 corners 数组中
                corners[k] = Mat.FromArray<Point3f>(p);
            }
            return corners;
        }

        // 计算重投影误差
        private double ComputeReprojectionErrors(Mat[] objectPoints, Mat[] imagePoints, Mat[] rvecs, Mat[] tvecs, Mat cameraMatrix, Mat distCoeffs)
        {
            Mat imagePoints2 = new Mat();
            int totalPoints = 0;
            double totalErr = 0, err;

            for (int i = 0; i < objectPoints.Length; ++i)
            {
                Cv2.ProjectPoints(objectPoints[i], rvecs[i], tvecs[i], cameraMatrix, distCoeffs, imagePoints2);

                err = Cv2.Norm(imagePoints[i], imagePoints2, NormTypes.L2);

                int n = objectPoints[i].Width * objectPoints[i].Height;
                totalErr += err * err;
                totalPoints += n;
            }

            return Math.Sqrt(totalErr / totalPoints);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (pictureBox2.Image == null)
            {
                return;
            }
            Bitmap output = new Bitmap(pictureBox2.Image);
            var sdf = new SaveFileDialog();
            sdf.Title = "保存";
            sdf.Filter = "Images (*.jpg)|*.jpg|Images (*.png)|*.png|Images (*.bmp)|*.bmp|Images (*.emf)|*.emf|Images (*.exif)|*.exif|Images (*.gif)|*.gif|Images (*.ico)|*.ico|Images (*.tiff)|*.tiff|Images (*.wmf)|*.wmf";
            if (sdf.ShowDialog() == DialogResult.OK)
            {
                switch (sdf.FilterIndex)
                {
                    case 1:
                        {
                            output.Save(sdf.FileName, ImageFormat.Jpeg);
                            break;
                        }
                    case 2:
                        {
                            output.Save(sdf.FileName, ImageFormat.Png);
                            break;
                        }
                    case 3:
                        {
                            output.Save(sdf.FileName, ImageFormat.Bmp);
                            break;
                        }
                    case 4:
                        {
                            output.Save(sdf.FileName, ImageFormat.Emf);
                            break;
                        }
                    case 5:
                        {
                            output.Save(sdf.FileName, ImageFormat.Exif);
                            break;
                        }
                    case 6:
                        {
                            output.Save(sdf.FileName, ImageFormat.Gif);
                            break;
                        }
                    case 7:
                        {
                            output.Save(sdf.FileName, ImageFormat.Icon);
                            break;
                        }
                    case 8:
                        {
                            output.Save(sdf.FileName, ImageFormat.Tiff);
                            break;
                        }
                    case 9:
                        {
                            output.Save(sdf.FileName, ImageFormat.Wmf);
                            break;
                        }
                }
                MessageBox.Show("保存成功,位置:" + sdf.FileName);
            }
        }

    }
}

下载

源码下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1662900.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2019年计算机真题

2019年计算机真题 离散数学 一、用逻辑符号表达下列语句(论域为包含一切事物的集合) 1&#xff09;过平面上的两个点&#xff0c;有且仅有一条直线通过。 解: (1) P ( x , y ) : x , y \mathrm{P}_{(\mathrm{x}, \mathrm{y})}: \mathrm{x}, \mathrm{y} P(x,y)​:x,y 是平面上的…

线性表

1.1线性表的定义 线性表&#xff1a;零个或多个数据元素的有限序列。 注&#xff1a; &#xff08;1&#xff09;它是一个序列。元素之间是有顺序的&#xff0c;若元素存在多个&#xff0c;则第一个元素无前驱&#xff0c;最后一个元素无后继&#xff0c;其他元素有且只有一个…

SpringBoot 使用logback(多环境配置)

Logback是由log4j创始人设计的又一个开源日志组件。可用于项目日志功能。官网地址 第1步&#xff1a;添加坐标依赖 <!--logback--> <dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version…

该问题未得到解决(仅记录)

https://releases.ubuntu.com/bionic/进入网页下载ubuntu 选择烧录软件将下载的Ubuntu烧录到U盘中 之前用这个U盘烧录过一次&#xff0c;成功了&#xff0c;后来应该是U盘受损或者是什么其他原因使得用这个U盘总是烧录失败

网安面经之xss漏洞

目录 一、XSS漏洞 1、xss漏洞原理与危害 2、xss的类型&#xff1f;区别&#xff1f;修复&#xff1f; 3、常见使用的标签&#xff0c;payload构造 一、XSS漏洞 1、xss漏洞原理与危害 原理&#xff1a;xss就是跨站脚本攻击漏洞&#xff0c;也可以理解为前端的代码注入&…

数字人金融应用技术指南

根据《北京金融科技产业联盟团体标准管理办法》的规定&#xff0c;2024年3月27日经北京金融科技产业联盟第三届理事会第二次会议审议&#xff0c;批准发布《数字人金融应用技术指南》&#xff08;T/BFIA 027—2024&#xff09;、《图数据库金融应用技术要求》&#xff08;T/BFI…

医院转型新突破:精益六西格玛助力管理费大降13%,业务飙升26%

近年来&#xff0c;越来越多的医院开始尝试引入精益六西格玛管理模式&#xff0c;以期实现管理费的降低和业务量的增长。那么&#xff0c;精益六西格玛模式真的有这么牛吗&#xff1f;深圳天行健六西格玛培训公司将从实践角度出发&#xff0c;探讨精益六西格玛如何助力医院实现…

GAME101-Lecture06学习

前言 上节课主要讲的是三角形的光栅化。重要的思想是要利用像素的中心对三角形可见性的函数进行采样。 这节课主要就是反走样。 课程链接&#xff1a;Lecture 06 Rasterization 2 (Antialiasing and Z-Buffering)_哔哩哔哩_bilibili 反走样引入 ​ 通过采样&#xff0c;得到…

Vuex核心概念-state状态

目录 一、目标 二、提供数据 三、使用数据 1.通过store直接访问 2.通过辅助函数&#xff08;简化&#xff09; 一、目标 明确如何给仓库提供数据&#xff0c;如何使用仓库的数据 二、提供数据 State提供唯一的公共数据源&#xff0c;所有共享的数据都要统一放到Store中的…

了解 条码工具 Dynamsoft 在条码读取器中的形态运算

在图像处理中&#xff0c;术语形态学是指分析形状以填充小孔、去除噪声、提取轮廓等的一组操作。形态学操作很像空间卷积中的过滤过程。有两个部分在起作用&#xff1a;结构元素和预定义的计算规则。 点击下载Dynamsoft最新版https://www.evget.com/product/3691/download 结…

C#上位机1ms级高精度定时任务

precisiontimer 安装扩展包 添加引用 完整代码 using PrecisionTiming;using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; us…

Java数组(二)

Java数组&#xff08;二&#xff09; 1、多维数组 多维数组可以看成是数组的数组&#xff0c;比如二维数组就是一个特殊的一维数组&#xff0c;其每一个元素都是一个一维数组。二维数组 int a[][] new int[2][5];解析&#xff1a;以上二维数组a可以看成一个两行五列的数组。…

七、Redis三种高级数据结构-HyperLogLog

Redis HyperLogLog是用来做基数统计的算法&#xff0c;HyperLogLog在优点是&#xff0c;在输入的元素的数量或者体积非常大时&#xff0c;计算基数占用的空间总是固定的、并且非常小。在Redis里每个HyperLogLog键只需花费12KB内存&#xff0c;就可以计算接近 264 个元素的基数。…

政安晨【零基础玩转各类开源AI项目】:基于Ubuntu系统本地部署使用GPT-SoVITS进行语音克隆与TTS语音生成

目录 介绍 什么是TTS 安装Miniconda 框架功能 测试通过的环境 开始 1. 安装好miniconda 2. 进入下载的GPT-SoVITS目录 3. 创建虚拟环境并执行脚本 4. 执行过程中可能会出错 5. 下载预训练模型 6. 训练过程中可能会报错 7. 使用过程中可能出错 8.以下是使用全过程…

Java入门基础学习笔记8——注释

1、注释&#xff1a; 注释是写在程序中对代码进行解释说明的文件&#xff0c;方便自己和其他人查看&#xff0c;以便理解程序的。 package cn.ensource.note;/**文档注释文档注释 */ public class NoteDemo {public static void main(String[] args) {// 单行注释System.out.…

Vue从入门到实战Day04

一、组件的三大组成部分&#xff08;结构/样式/逻辑&#xff09; 1. scoped样式冲突 默认情况&#xff1a;写在组件中的样式会全局生效 -> 因此很容易造成多个组件之间的样式冲突问题。 1. 全局样式&#xff1a;默认组件中的样式会作用到全局 2. 局部样式&#xff1a;可以…

电脑开机显示器不亮?3大原因及解决办法

电脑开机后&#xff0c;显示器不亮是一个常见的问题&#xff0c;可能会给用户带来困扰。然而&#xff0c;这个问题通常并不复杂&#xff0c;可以通过一些简单的方法来解决。在本文中&#xff0c;我们将介绍三种常见的方法&#xff0c;帮助您解决电脑开机显示器不亮的情况。这些…

AI作画涉及的深度学习算法

AI作画中使用的深度学习算法多种多样&#xff0c;这些算法主要基于神经网络的结构和训练方式&#xff0c;以生成和改进艺术作品。以下是一些在AI作画中常用的深度学习算法&#xff1a; 生成对抗网络&#xff08;GANs, Generative Adversarial Networks&#xff09;&#xff1a…

vue3 antd-vue 超简单方式实现a-table跨页勾选

一、效果如下&#xff1a; 第一页勾选了2&#xff0c; 3&#xff0c; 4 翻到第三页勾选24&#xff0c; 25 回显&#xff0c;如比返回第一页的时候触发分页改变&#xff0c; 在映射中的第一页的数据给到a-table绑定的state.selectedRowKeys即可&#xff0c;如下方法 二、勾选思路…

【深度学习】Diffusion扩散模型原理解析1

1、前言 diffusion&#xff0c;这几年一直很火的模型&#xff0c;比如这段时间在网上的文生图大模型——Stable diffusion。就是以diffusion作为基底模型&#xff0c;但由于该模型与VAE那边&#xff0c;都涉及了较多了概率论知识&#xff0c;实在让人望而却步。所以&#xff0…