三维点云机器学习检测定位圆心,三维圆检测,拟合轴线(基于open3d和python)

news2024/10/7 20:32:25

0.任务描述

  • 背景:从端面拍摄大型圆筒工件,该工件周向尺寸大于相机视野,只能拍摄到1/3左右的圆周,且无法保证相机与端面垂直拍摄
    在这里插入图片描述

  • 任务:需要拟合圆周与轴线位置

  • 难点:三维圆拟合与检测都很复杂,没有方便可用的成熟方案,最小二乘法既无法处理高维情况,也会受异常点干扰,RANSAC的检测迭代次数过多,选点的随机性过大

  • 基本思路:通过深度信息过滤干扰平面,使用RANSAC算法检测最大平面作为圆筒端面,在该端面上随机选取一个点作为初始化圆心,以最小化所有点到圆心的距离差作为优化目标,求解最优化问题,得到圆心和半径,结合端面法向量可以求出轴线方程。

  • 相关数据:深度信息过滤后的点云数据下载

1.加载显示原始点云

  • 目录结构:数据都存在duanmian 文件夹下,本文用力为第三次拍摄,存在3文件夹下:
file = '3'
file_before = 'duanmian/'
pcd = o3d.io.read_point_cloud(file_before + file + '/point_cloud_00000.ply')
  • 原始点云全白,与显示的背景色重合无法有效可视化,所以需要改变颜色,这里改为了全黑
points = np.array(pcd.points)
colors = np.zeros(np.array(pcd.points).shape[0])
pcd.colors = o3d.utility.Vector3dVector(np.zeros(np.array(pcd.colors).shape))
o3d.visualization.draw_geometries([pcd])

在这里插入图片描述

2.点云预处理

  • 均匀降采样:保证点的位置准确度的同时方便存储与后续计算
pcd = pcd.uniform_down_sample(every_k_points = 20)
o3d.visualization.draw_geometries([pcd])

在这里插入图片描述

  • 存储降采样后的原始点云,方便后期对比与效果展示:
o3d.io.write_point_cloud(file_before + file + '/old.ply', pcd)
  • RANSAC平面检测分割(详细解释参考这里):
plane_model, inliers = pcd.segment_plane(distance_threshold=3 * 1e-3,
                                         ransac_n=3,
                                         num_iterations=1000)
[a, b, c, d] = plane_model
print(f"Plane equation: {a:.2f}x + {b:.2f}y + {c:.2f}z + {d:.2f} = 0")

inlier_cloud = pcd.select_by_index(inliers)
outlier_cloud = pcd.select_by_index(inliers, invert=True)
  • 进一步滤波,滤去离群干扰点(在端面平面内但明显不在圆周上的点)
  • 有两种常用方法:统计滤波和半径滤波(参考博文)
    • 统计滤波:
    #统计滤波
    # nb_neighbors:最近k个点    std_ratio:基于标准差的阈值,越小滤除点越多
    cl,ind = inlier_cloud.remove_statistical_outlier(nb_neighbors=3, std_ratio=1)
    inlier_cloud = inlier_cloud.select_by_index(ind)
    inlier_cloud.paint_uniform_color([1.0, 0, 0])
    outlier_cloud2 = inlier_cloud.select_by_index(ind, invert=True)
    
    • 半径滤波:
    #半径滤波
    # nb_points:基于球体内包含点数量的阈值  radius:半径
    cl,ind = inlier_cloud.remove_radius_outlier(nb_points=3, radius = 1.0)
    inlier_cloud = inlier_cloud.select_by_index(ind)
    
    • 实际效果来看统计滤波效果更好,半径滤波需要设定半径的大小,常常无法在保留内点的同时过滤离群点
  • 之后需要被拟合的点都存在了inlier_cloud中

3.构建学习模型

  • model(points: torch.tensor, cir: torch.tensor, line: torch.tensor)
  • 传入待拟合点,待优化圆心(二维),端面平面方程,使用端面方程去计算圆心的三维坐标,这样可以保证优化过程中圆心始终在端面平面内
def model(points: torch.tensor, cir: torch.tensor, line: torch.tensor):
    '''
    功能:
        根据圆心和待拟合点计算损失
    输入:
        待拟合点,待优化圆心(二维),端面平面方程
    输出:
        圆心,半径,损失
    '''
    line = line.float()
    points = points.float()
    cir = cir.float()

    #计算圆心三维坐标
    cir_z = torch.matmul(cir, line[0:2].T) + line[-1]
    cir_z = cir_z / (1e-10 - line[2])
    cir_z = cir_z.unsqueeze(0)
    cir = torch.cat([cir, cir_z], 0)

    #计算半径矩阵和损失
    #损失一定程度上表示每个点到圆心的距离的差距
    points = points - cir
    points = torch.matmul(points, points.T)
    points = torch.diag(points)
    n_all = points.shape[0]
    r_all = torch.sum(points) / (n_all ** 1)
    e = 0
    for i in range(1,4):
        n = int(n_all / i)
        r = torch.sum(points[:n]) / (n ** 1)
        e += ((r - r_all) ** 2 ) 
    
    return cir, r_all ** 0.5, e

4.训练模型

  • 数据准备
points_2 = np.array(inlier_cloud.points) #* 100
cir =torch.from_numpy(points_2[0][0:2])
cir.requires_grad = True
points_2 = torch.from_numpy(points_2)
line = torch.Tensor(np.array([a, b, c, d]))
  • 模型训练:采用分段学习率,每5000次更新打印一次信息
learning_rate_o = 1e-3
learning_rate_2 = 1e-2
learning_rate_3 = 1
learning_rate_4 = 8
repect_n = 0
repect = 0
epoch = 0
jingdu = 1e-28
epoch_max = 5 * 1e5
print('-------开始学习---------')
while(True):
    epoch += 1
    if cir.grad is not None:
        #梯度归零
        cir.grad.zero_()
    #前向传播
    _, r, l = model(points_2, cir, line)
    #反向传播
    l.backward()
    if cir.grad is None:
        #梯度爆炸就及时退出
        print('++++++++++++')
        print('epoch:', epoch)
        print('a:', cir)
        print('grad:', cir.grad)
        print('r:', r)
        break
    
    #分段学习率
    if l  < 100:
        learning_rate = learning_rate_2
        if l < 45:
            learning_rate = learning_rate_3
            if l < 0.2:
                learning_rate = learning_rate_4
            else:learning_rate = learning_rate_3
        else:learning_rate = learning_rate_2
    else:
        learning_rate = learning_rate_o
    
    
    with torch.no_grad():
        cir -= learning_rate * cir.grad
        if epoch % 5e3 == 0:
            print('------------------')
            print('epoch:',epoch)
            print('a:', cir)
            print('grad:', cir.grad)
            print('rate:',learning_rate)
            print('loss:', l)
            print('r:', r.item())
        
        if l < jingdu:
            print('精度足够,停止学习')
            break
        if epoch > epoch_max:
            break
        
        if l == repect:
            repect_n += 1
        else:
            repect = l
            repect_n = 0
        
        if repect_n > 15:
            print('达到收敛停止学习')
            break
  • 打印最终训练结果:
print('*****************************')
print('epoch:',epoch)
print('a:', cir)
print('grad:', cir.grad)
print('rate:',learning_rate)
print('loss:', l)
print('r:', r.item())


cir, r, l = model(points_2, cir, line)
print('圆心坐标:(', cir, '),半径:', r.item())
  • 效果展示:
    在这里插入图片描述

  • 将圆心坐标存入inlier_cloud中:

see = np.row_stack([np.array(inlier_cloud.points), cir.detach().numpy()])
inlier_cloud.points = o3d.utility.Vector3dVector(see)
inlier_cloud.paint_uniform_color([1.0, 0, 0])

5.三维圆与轴线的散点计算

  • 已知圆心、半径、圆所在平面方程,计算该圆的散点和轴线散点:
#空间圆可视化https://www.doc88.com/p-813917521845.html
def get_points_of_circle_3d(line, cir, r):
    '''
    已知圆心、半径、圆所在平面方程,计算该圆的散点和轴线散点
    '''
    A, B, C, D = line
    #取平面上不贡献三个点,组成不共线两个向量
    p1 = np.array([0, 0, -1 * D / C])
    p2 = np.array([1, 0, (-1 * D - A) / C])
    p3 = np.array([0, 1, (-1 * D - B) / C])
    u1 = p1 - p2
    u2 = p1 - p3
    #法向量
    n = np.cross(u1, u2)
    n_cir = [cir + n * x  for x in np.arange(-0.1, 0.1, 0.001)]
    #print(n)
    #圆平面建立坐标系
    v = np.cross(u1, n)
    #转为单位向量
    u = u1 / (np.dot(u1, u1.T) ** 0.5)
    v = v / (np.dot(v, v.T) ** 0.5)
    #根据参数方程生成圆的散点
    import math
    p_cir = [cir + u * r * math.cos(x) + v * r * math.sin(x) for x in np.arange(0, 2*3.15 ,0.05)]
    return np.array(p_cir), np.array(n_cir)

6.可视化绘制与新点云保存

  • 计算结果与原始点云叠加显示:
p_cir, n_cir = get_points_of_circle_3d(line.detach().numpy(), cir.detach().numpy(), r.detach().numpy())
see = np.row_stack([cir.detach().numpy(), p_cir, n_cir])
cir_cloud = o3d.geometry.PointCloud()
cir_cloud.points = o3d.utility.Vector3dVector(see)
cir_cloud.paint_uniform_color([0, 1.0, 0])
o3d.visualization.draw_geometries([inlier_cloud, outlier_cloud, outlier_cloud, cir_cloud])
  • 新建点云保存结果:
new_pcd = o3d.geometry.PointCloud()
new_pcd.points = o3d.utility.Vector3dVector(np.row_stack([np.array(inlier_cloud.points),
                                                                                            np.array(outlier_cloud.points),
                                                                                            np.array(outlier_cloud2.points),
                                                                                            np.array(cir_cloud.points)]))
new_pcd.colors = o3d.utility.Vector3dVector(np.row_stack([np.array(inlier_cloud.colors),
                                                                                        np.array(outlier_cloud.colors),
                                                                                        np.array(outlier_cloud2.colors),
                                                                                        np.array(cir_cloud.colors)]))
o3d.io.write_point_cloud(file_before + file + '/new.ply', new_pcd)

7.最终效果

  • 绿色为计算拟合出来的散点圆弧和轴线
  • 红色内用来拟合的内点
  • 黑色为过滤出去的外点(离群点)
    在这里插入图片描述

8.完整代码

import open3d as o3d
import numpy as np
from numpy.linalg import det
import random
import torch

def model(points: torch.tensor, cir: torch.tensor, line: torch.tensor):
    '''
    功能:
        根据圆心和待拟合点计算损失
    输入:
        待拟合点,待优化圆心(二维),端面平面方程
    输出:
        圆心,半径,损失
    '''
    line = line.float()
    points = points.float()
    cir = cir.float()

    #计算圆心三维坐标
    cir_z = torch.matmul(cir, line[0:2].T) + line[-1]
    cir_z = cir_z / (1e-10 - line[2])
    cir_z = cir_z.unsqueeze(0)
    cir = torch.cat([cir, cir_z], 0)

    #计算半径矩阵和损失
    #损失一定程度上表示每个点到圆心的距离的差距
    points = points - cir
    points = torch.matmul(points, points.T)
    points = torch.diag(points)
    n_all = points.shape[0]
    r_all = torch.sum(points) / (n_all ** 1)
    e = 0
    for i in range(1,4):
        n = int(n_all / i)
        r = torch.sum(points[:n]) / (n ** 1)
        e += ((r - r_all) ** 2 ) 
    
    return cir, r_all ** 0.5, e

file = '3'
file_before = 'duanmian/'
pcd = o3d.io.read_point_cloud(file_before + file + '/point_cloud_00000.ply')

#pcd = pcd.voxel_down_sample(voxel_size=5e-3)
points = np.array(pcd.points)
colors = np.zeros(np.array(pcd.points).shape[0])
pcd.colors = o3d.utility.Vector3dVector(np.zeros(np.array(pcd.colors).shape))
#o3d.visualization.draw_geometries([pcd])
pcd = pcd.uniform_down_sample(every_k_points = 20)
#o3d.visualization.draw_geometries([pcd])

o3d.io.write_point_cloud(file_before + file + '/old.ply', pcd)

plane_model, inliers = pcd.segment_plane(distance_threshold=3 * 1e-3,
                                         ransac_n=3,
                                         num_iterations=1000)
[a, b, c, d] = plane_model
print(f"Plane equation: {a:.2f}x + {b:.2f}y + {c:.2f}z + {d:.2f} = 0")

inlier_cloud = pcd.select_by_index(inliers)
outlier_cloud = pcd.select_by_index(inliers, invert=True)

print('------开始滤波------')
#参考https://blog.csdn.net/skycol/article/details/127429843
#统计滤波
# nb_neighbors:最近k个点    std_ratio:基于标准差的阈值,越小滤除点越多
cl,ind = inlier_cloud.remove_statistical_outlier(nb_neighbors=3, std_ratio=1)
inlier_cloud = inlier_cloud.select_by_index(ind)
inlier_cloud.paint_uniform_color([1.0, 0, 0])
outlier_cloud2 = inlier_cloud.select_by_index(ind, invert=True)
#半径滤波
# nb_points:基于球体内包含点数量的阈值  radius:半径
#cl,ind = inlier_cloud.remove_radius_outlier(nb_points=3, radius = 1.0)
#inlier_cloud = inlier_cloud.select_by_index(ind)

# o3d.visualization.draw_geometries([inlier_cloud, outlier_cloud, outlier_cloud2])

points_2 = np.array(inlier_cloud.points) #* 100
cir =torch.from_numpy(points_2[0][0:2])#选取第一个点作为初始化圆心
cir.requires_grad = True
points_2 = torch.from_numpy(points_2)
line = torch.Tensor(np.array([a, b, c, d]))

learning_rate_o = 1e-3
learning_rate_2 = 1e-2
learning_rate_3 = 1
learning_rate_4 = 8
repect_n = 0
repect = 0
epoch = 0
jingdu = 1e-28
epoch_max = 5 * 1e5
print('-------开始学习---------')
while(True):
    epoch += 1
    if cir.grad is not None:
        #梯度归零
        cir.grad.zero_()
    #前向传播
    _, r, l = model(points_2, cir, line)
    #反向传播
    l.backward()
    if cir.grad is None:
        #梯度爆炸就及时退出
        print('++++++++++++')
        print('epoch:', epoch)
        print('a:', cir)
        print('grad:', cir.grad)
        print('r:', r)
        break
    
    #分段学习率
    if l  < 100:
        learning_rate = learning_rate_2
        if l < 45:
            learning_rate = learning_rate_3
            if l < 0.2:
                learning_rate = learning_rate_4
            else:learning_rate = learning_rate_3
        else:learning_rate = learning_rate_2
    else:
        learning_rate = learning_rate_o
    
    
    with torch.no_grad():
        cir -= learning_rate * cir.grad
        if epoch % 5e3 == 0:
            print('------------------')
            print('epoch:',epoch)
            print('a:', cir)
            print('grad:', cir.grad)
            print('rate:',learning_rate)
            print('loss:', l)
            print('r:', r.item())
        
        if l < jingdu:
            print('精度足够,停止学习')
            break
        if epoch > epoch_max:
            break
        
        if l == repect:
            repect_n += 1
        else:
            repect = l
            repect_n = 0
        
        if repect_n > 15:
            print('达到收敛停止学习')
            break

print('*****************************')
print('epoch:',epoch)
print('a:', cir)
print('grad:', cir.grad)
print('rate:',learning_rate)
print('loss:', l)
print('r:', r.item())


cir, r, l = model(points_2, cir, line)
print('圆心坐标:(', cir, '),半径:', r.item())
see = np.row_stack([np.array(inlier_cloud.points), cir.detach().numpy()])
inlier_cloud.points = o3d.utility.Vector3dVector(see)
inlier_cloud.paint_uniform_color([1.0, 0, 0])
#o3d.visualization.draw_geometries([inlier_cloud, outlier_cloud])

#空间圆可视化https://www.doc88.com/p-813917521845.html
def get_points_of_circle_3d(line, cir, r):
    '''
    已知圆心、半径、圆所在平面方程,计算该圆的散点和轴线散点
    '''
    A, B, C, D = line
    #取平面上不贡献三个点,组成不共线两个向量
    p1 = np.array([0, 0, -1 * D / C])
    p2 = np.array([1, 0, (-1 * D - A) / C])
    p3 = np.array([0, 1, (-1 * D - B) / C])
    u1 = p1 - p2
    u2 = p1 - p3
    #法向量
    n = np.cross(u1, u2)
    n_cir = [cir + n * x  for x in np.arange(-0.1, 0.1, 0.001)]
    #print(n)
    #圆平面建立坐标系
    v = np.cross(u1, n)
    #转为单位向量
    u = u1 / (np.dot(u1, u1.T) ** 0.5)
    v = v / (np.dot(v, v.T) ** 0.5)
    #根据参数方程生成圆的散点
    import math
    p_cir = [cir + u * r * math.cos(x) + v * r * math.sin(x) for x in np.arange(0, 2*3.15 ,0.05)]
    return np.array(p_cir), np.array(n_cir)

p_cir, n_cir = get_points_of_circle_3d(line.detach().numpy(), cir.detach().numpy(), r.detach().numpy())
see = np.row_stack([cir.detach().numpy(), p_cir, n_cir])
cir_cloud = o3d.geometry.PointCloud()
cir_cloud.points = o3d.utility.Vector3dVector(see)
cir_cloud.paint_uniform_color([0, 1.0, 0])
o3d.visualization.draw_geometries([inlier_cloud, outlier_cloud, outlier_cloud, cir_cloud])

new_pcd = o3d.geometry.PointCloud()
new_pcd.points = o3d.utility.Vector3dVector(np.row_stack([np.array(inlier_cloud.points),
                                                                                            np.array(outlier_cloud.points),
                                                                                            np.array(outlier_cloud2.points),
                                                                                            np.array(cir_cloud.points)]))
new_pcd.colors = o3d.utility.Vector3dVector(np.row_stack([np.array(inlier_cloud.colors),
                                                                                        np.array(outlier_cloud.colors),
                                                                                        np.array(outlier_cloud2.colors),
                                                                                        np.array(cir_cloud.colors)]))
o3d.io.write_point_cloud(file_before + file + '/new.ply', new_pcd)

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

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

相关文章

fscan安装配置(windows、linux系统)

fscan安装配置(windows、linux系统) 1、简介 fscan一款内网综合扫描工具&#xff0c;方便一键自动化、全方位漏扫扫描。 它支持主机存活探测、端口扫描、常见服务的爆破、ms17010、redis批量写公钥、计划任务反弹shell、读取win网卡信息、web指纹识别、web漏洞扫描、netbios探…

程序员面试必备的 Java 八股文,适合所有的 Java 求职者

说明 本文分享 Java 后端真实高频面试题&#xff0c;有详细答案&#xff0c;保你稳过面试。题目包括&#xff1a;Java 基础、多线程、JVM、数据库、Redis、Shiro、Spring、SpringBoot、MyBatis、MQ、ELK、SpringCloud、设计模式等。 包含从简单到困难、从高频到低频的题目&…

EF Core中Partition by实现

一、SQL语句实现 Partition by是SQL Server数据库中提供的分区函数,跟Group by不同的是,Partition by能够按照分区返回所有记录,而Group by只能返回一条记录。 举个例子,有如下的数据库,需要找出每个唯一编号最新状态的数据。 显然,CW048201和CW048202它们的最新状态都…

靠着这套Github标星55K的Java面试笔记,成功拿到了2个大厂offer

作为一名优秀的程序员&#xff0c;技术面试是不可避免的一个环节&#xff0c;一般技术面试官都会通过自己的方式去考察程序员的技术功底与基础理论知识。 如果你参加过一些大厂面试&#xff0c;肯定会遇到一些这样的问题&#xff1a; 1、看你项目都用的框架&#xff0c;熟悉S…

Linux 环境下Docker将镜像打包导出到本地,上传至内网服务器(八)

文章目录 背景1. docker容器打包成镜像和压缩&#xff08;1&#xff09;首先查看镜像所在的容器&#xff0c;获取到容器id&#xff08;2&#xff09;将容器保存成镜像&#xff08;3&#xff09;将镜像打包&#xff08;4&#xff09;将镜像包压缩 2. docker镜像压缩包解压及镜像…

2023最新发布:Java 面试突击大全 带你摸熟 20+ 互联网公司面试考点

对于程序员来说&#xff0c;春招的失利意味着在金九银十要打一场“硬战”&#xff0c;可又有多少人做好了面试的准备呢&#xff1f;对于一线互联网公司的面试&#xff0c;你又了解多少呢&#xff1f; 今天&#xff0c;一本《Java 面试考点大全》全网首发&#xff0c;带你摸熟 …

阿里8年,肝到P7只剩这份笔记了,帮朋友拿了7个Offer....

时光飞逝&#xff0c;转眼间在阿里工作了8年&#xff0c;工作压力大&#xff0c;节奏快&#xff0c;但是从技术上确实得到了成长&#xff0c;尤其是当你维护与大促相关的系统的时候&#xff0c;熬到P7也费了不少心思 我的职业生涯开始和大多数测试人一样&#xff0c;刚开始接触…

大话设计模式——享元

享元&#xff08;Flyweight&#xff09; Intent 利用共享的方式来支持大量细粒度的对象&#xff0c;这些对象一部分内部状态是相同的。 Class Diagram Flyweight&#xff1a;享元对象IntrinsicState&#xff1a;内部状态&#xff0c;享元对象共享内部状态ExtrinsicState&am…

【架构设计】单点登录实现技术方案

序言 你只管努力&#xff0c;其他交给时间&#xff0c;时间会证明一切。 文章标记颜色说明&#xff1a; 黄色&#xff1a;重要标题红色&#xff1a;用来标记结论绿色&#xff1a;用来标记一级论点蓝色&#xff1a;用来标记二级论点 1 基本介绍 1.1 什么是单点登录 单点登录&am…

命令模式(十七)

相信自己&#xff0c;请一定要相信自己 上一章简单介绍了模板模式(十六), 如果没有看过, 请观看上一章 一. 命令模式 定义&#xff1a;将一个请求封装为一个对象&#xff0c;使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通&#xff0c; 这样方便…

智能锁语音芯片方案,NV170D-SOP8九芯电子自主研发

随着智能家居市场的不断壮大&#xff0c;智能门锁已经成为越来越多家庭不可或缺的一部分。传统的机械锁门的开锁方式已经无法满足人们对安全和便捷性的需求。而电子锁门随着技术的不断突破&#xff0c;拥有了更为丰富的功能和更高的安全性。 但是&#xff0c;目前市场上有那么…

1.4.2:DHTMLX JS 看板 DHTMLX JS Kanban Board Crack

用于任务管理应用 程序的 敏捷 JavaScript 看板&#xff0c;使用 DHTMLX JavaScript 看板库开发成熟的 Web 应用程序&#xff0c;以获得对工作量的完全控制并有效地管理任务。 开始使用 DHTMLX JS 看板 DHTMLX 看板允许创建任意数量的任务并通过右侧面板编辑它们。用户可以编…

uCOSii的任务延时和软件定时器

uCOSii的任务延时和软件定时器 1、心跳节拍 操作系统的心跳节拍称为一个Tick。uCOSii中有一个专用的心跳节拍函数&#xff1a;OSTimeTick()&#xff0c;每调用一次&#xff0c;系统时间计数器OSTime计数器就会加1次。为了能调用这个心跳节拍函数&#xff0c;我们使用CPU的滴答…

极致呈现系列之:Echarts地图的浩瀚视野(二)

今天我将基于上一个博客讲到的Echarts地图的相关知识&#xff0c;来实现一个三维地图的效果&#xff0c;我将通过两种方式来实现&#xff0c;一种是伪3D效果的中国地图效果&#xff0c;为什么说是伪3D效果呢&#xff0c;跟着做完你就明白了&#xff1b;一种是真正的三维效果中国…

Eclipse添加Spket插件实现ExtJs智能提示

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、使用步骤1.解压Spket插件2.重启 Eclipse3.配置 Spket4.添加 Library5.添加 File6.将 extjs 设置为 Default7.将 *.js 文件的默认编辑器设置为 Spket JavaSc…

本地连接服务器搭建的 Redis 集群

本地连接服务器搭建的 Redis 集群 在实际运行测试中&#xff0c;存在两个问题 安全组或防火墙开放端口 主要开放10000端口。如果要连接 Redis集群的应用服务不和 Redis集群在一个局域网下&#xff0c;会出现连接异常。 第一个问题检查防火墙或安全组就可以解决&#xff0c;第…

我为开放原子全球开源峰会助力

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

Linux运维监控学习笔记1

1. 监控系统的概念&#xff1a; 监控系统&#xff0c;将所有需要监控的服务器及其各种各种需要的状态数据都实时地收集&#xff0c;并图形化地展示&#xff0c;并可以进行报警&#xff0c;让机器主动及时地与人沟通。 2. 为什么要监控&#xff1f; 答&#xff1a;实时地收集数…

练习:逻辑回归

练习2&#xff1a;逻辑回归 介绍 在本练习中&#xff0c;您将实现逻辑回归并将其应用于两个不同的数据集。还将通过将正则化加入训练算法&#xff0c;来提高算法的鲁棒性&#xff0c;并用更复杂的情形来测试模型算法。 在开始练习前&#xff0c;需要下载如下的文件进行数据上…

【开发细节】SpringBoot配置文件的spring.profiles下的active和include属性的区别和作用

目录 问题作用spring.profiles.activespring.profiles.include 总结 问题 我们经常在项目的application.yml中看到这样的配置&#xff0c;如下&#xff1a; 在 Spring Boot 中&#xff0c;spring.profiles.active 和 spring.profiles.include 属性都是用来配置 profile 的。 …