OpenCV 轮廓分析实战:从检测到形状匹配的完整指南

轮廓(Contour)是图像中连续且具有相同灰度值的像素集合,是描述目标形状、位置和结构的核心特征。在计算机视觉中,轮廓分析广泛应用于目标定位、形状识别、尺寸测量等场景(如工业零件检测、手写数字识别)。本文将基于用户提供的代码,系统解析轮廓检测的完整流程,包括轮廓提取、属性计算(重心、面积、周长)、形状逼近、包围结构拟合、特征点定位及形状匹配等核心操作。

一、轮廓检测基础:从二值图像到轮廓提取

轮廓检测的前提是图像二值化(只有黑白两色,前景目标为白色,背景为黑色),因为轮廓是基于像素灰度的连续性提取的。OpenCV 通过cv2.findContours()函数实现轮廓检测,需明确其参数含义和返回值。

1. 核心流程:二值化 → 轮廓检测

用户代码的第一步是将彩色图转灰度图,再通过阈值处理得到二值图,最终提取轮廓。这是轮廓检测的标准前置流程:

import cv2
import numpy as np# 1. 读取图像并预处理(灰度化 + 二值化)
# 处理第一张图(02.png)
img1 = cv2.imread('02.png')
img1_gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)  # 转灰度图(减少计算量)
# 阈值二值化:>127设为255(白色,前景),<127设为0(黑色,背景)
ret1, thresh1 = cv2.threshold(img1_gray, 127, 255, cv2.THRESH_BINARY)# 处理第二张图(1.jpg)
img2 = cv2.imread('1.jpg')
img2_gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
ret2, thresh2 = cv2.threshold(img2_gray, 127, 255, cv2.THRESH_BINARY)# 2. 提取轮廓:cv2.findContours(二值图, 轮廓检索模式, 轮廓逼近方法)
# 返回值:contours(轮廓列表,每个轮廓是像素坐标数组)、hierarchy(轮廓层级关系)
contours1, hierarchy1 = cv2.findContours(thresh1, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
contours2, hierarchy2 = cv2.findContours(thresh2, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)# 取第一个轮廓(假设图像中只有一个主要目标)
cnt1 = contours1[0]  # 第一张图的轮廓
cnt2 = contours2[0]  # 第二张图的轮廓# (可选)绘制轮廓以便可视化:cv2.drawContours(原图, 轮廓列表, 轮廓索引, 颜色, 线宽)
cv2.drawContours(img1, [cnt1], 0, (0, 255, 0), 2)  # 绿色绘制轮廓,线宽2
cv2.imshow('Contour of 02.png', img1)
cv2.waitKey(0)
cv2.destroyAllWindows()

2. cv2.findContours()关键参数解析

参数取值与含义
轮廓检索模式(mode)cv2.RETR_LIST:仅提取所有轮廓,不建立层级关系(简单场景首选);
cv2.RETR_EXTERNAL:仅提取最外层轮廓(排除嵌套轮廓);
cv2.RETR_CCOMP:建立两层层级(外层 / 内层)。
轮廓逼近方法(method)cv2.CHAIN_APPROX_SIMPLE:压缩轮廓,只保留角点(如矩形只保留 4 个顶点,减少内存);
cv2.CHAIN_APPROX_NONE:保留所有轮廓像素点(精度高但内存大)。

二、轮廓属性计算:量化目标的形状与位置

轮廓属性是描述目标特征的量化指标,包括重心、面积、周长等,是后续形状分析的基础。用户代码中注释了这些属性的计算方法,以下是完整实现与解析。

1. 矩与重心(目标中心定位)

图像的 “矩” 是像素灰度的统计特征,通过矩可以计算目标的重心(几何中心),适用于目标定位(如机器人抓取目标中心)。

# 计算轮廓的矩(moments):包含一阶矩、二阶矩等统计信息
M1 = cv2.moments(cnt1)  # 第一张图轮廓的矩# 重心坐标公式:cx = m10/m00,cy = m01/m00(m00是零阶矩,即轮廓面积)
cx1 = int(M1['m10'] / M1['m00'])  # 重心x坐标
cy1 = int(M1['m01'] / M1['m00'])  # 重心y坐标# 在原图上绘制重心(红色圆点,填充)
cv2.circle(img1, (cx1, cy1), 5, (0, 0, 255), -1)
cv2.putText(img1, f'Center: ({cx1}, {cy1})', (cx1+10, cy1), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)cv2.imshow('Contour with Center', img1)
cv2.waitKey(0)
cv2.destroyAllWindows()

2. 面积与周长(目标大小量化)

  • 面积:轮廓包围的像素总数(通过cv2.contourArea()计算,或矩的m00值)。
  • 周长:轮廓的边界长度(通过cv2.arcLength()计算,需指定是否为 “闭合轮廓”)。
# 1. 计算面积(两种方法结果一致)
area1 = cv2.contourArea(cnt1)  # 直接计算轮廓面积
area1_via_moments = M1['m00']  # 通过矩的m00获取面积
print(f'Area of cnt1: {area1:.2f} (via contourArea), {area1_via_moments:.2f} (via moments)')# 2. 计算周长:参数2为True表示轮廓是闭合的(如圆形、矩形)
perimeter1 = cv2.arcLength(cnt1, closed=True)
print(f'Perimeter of cnt1: {perimeter1:.2f}')# 在原图上标注面积和周长
cv2.putText(img1, f'Area: {area1:.0f}', (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1)
cv2.putText(img1, f'Perimeter: {perimeter1:.0f}', (10, 40), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1)cv2.imshow('Contour with Area & Perimeter', img1)
cv2.waitKey(0)
cv2.destroyAllWindows()

三、形状逼近与包围结构:简化轮廓与边界拟合

对于复杂轮廓(如带毛刺的形状),需要通过形状逼近简化轮廓;同时,通过拟合包围结构(如轴对齐矩形、旋转矩形、圆),可快速获取目标的尺寸和姿态。

1. 多边形逼近(轮廓简化)

通过cv2.approxPolyDP()用更少的顶点拟合轮廓,核心参数是epsilon(逼近精度,通常设为周长的 0.01~0.1 倍),epsilon越小,拟合越接近原轮廓。

# 计算逼近精度epsilon(周长的10%,可调整)
epsilon1 = 0.1 * cv2.arcLength(cnt1, closed=True)# 多边形逼近:返回简化后的轮廓(顶点数组)
approx_cnt1 = cv2.approxPolyDP(cnt1, epsilon1, closed=True)# 绘制原轮廓(绿色)和简化轮廓(红色)
cv2.drawContours(img1, [cnt1], 0, (0, 255, 0), 2, label='Original Contour')
cv2.drawContours(img1, [approx_cnt1], 0, (0, 0, 255), 2, label='Approximated Contour')# 标注简化后的顶点数量
vertex_count = len(approx_cnt1)
cv2.putText(img1, f'Approx Vertices: {vertex_count}', (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)cv2.imshow('Original vs Approximated Contour', img1)
cv2.waitKey(0)
cv2.destroyAllWindows()

应用场景:形状分类(如通过顶点数判断是三角形(3 个顶点)、矩形(4 个顶点))。

2. 包围结构拟合(目标边界与姿态)

OpenCV 提供多种包围结构拟合函数,适用于不同场景(如轴对齐裁剪、旋转校正):

(1)轴对齐包围框(Bounding Rect)

拟合与图像坐标轴平行的矩形,仅需左上角坐标(x,y)和宽高(w,h),计算速度快。

# 拟合轴对齐包围框
x, y, w, h = cv2.boundingRect(cnt1)# 绘制包围框(蓝色)
cv2.rectangle(img1, (x, y), (x + w, y + h), (255, 0, 0), 2)
cv2.putText(img1, f'Bounding Rect: w={w}, h={h}', (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1)cv2.imshow('Bounding Rect', img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
(2)旋转包围框(Min Area Rect)

拟合面积最小的矩形(可旋转,与目标姿态一致),返回矩形的中心、宽高、旋转角度,适用于目标旋转校正。

# 拟合旋转包围框
min_area_rect = cv2.minAreaRect(cnt1)  # 返回 (中心(x,y), (宽,高), 旋转角度)
# 转换为矩形的4个顶点坐标(需整数化)
box_vertices = cv2.boxPoints(min_area_rect)
box_vertices = np.int0(box_vertices)  # 坐标转为整数# 绘制旋转包围框(紫色)
cv2.drawContours(img1, [box_vertices], 0, (255, 0, 255), 2)
cv2.putText(img1, f'Rot Angle: {min_area_rect[2]:.1f}°', (int(min_area_rect[0][0]), int(min_area_rect[0][1])), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 255), 1)cv2.imshow('Min Area Rect (Rotated)', img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
(3)最小外接圆与椭圆拟合
  • 最小外接圆:包围轮廓的最小圆形,适用于圆形目标的直径测量。
  • 椭圆拟合:用椭圆近似轮廓(要求轮廓至少有 5 个点),适用于椭圆形目标分析。
# 1. 最小外接圆
(x_circle, y_circle), radius = cv2.minEnclosingCircle(cnt1)
center_circle = (int(x_circle), int(y_circle))
radius = int(radius)
# 绘制外接圆(橙色)
cv2.circle(img1, center_circle, radius, (0, 165, 255), 2)# 2. 椭圆拟合(需轮廓点数量≥5)
if len(cnt1) >= 5:ellipse = cv2.fitEllipse(cnt1)  # 返回 (中心, (长轴,短轴), 旋转角度)# 绘制椭圆(青色)cv2.ellipse(img1, ellipse, (255, 255, 0), 2)cv2.imshow('Min Enclosing Circle & Ellipse', img1)
cv2.waitKey(0)
cv2.destroyAllWindows()

四、轮廓特征点与拓扑关系:深入分析目标结构

除了基础属性,轮廓的极值点(最左、最右、最上、最下)和凸包缺陷(目标凹陷处)能反映更精细的结构特征,而 “点与轮廓的关系” 可用于判断点是否在目标内部。

1. 轮廓极值点(目标边界极限位置)

通过寻找轮廓在 x/y 轴上的极值,确定目标的边界极限点(如物体的最右端、最顶端):

# 1. 最左点:x坐标最小的点
leftmost = tuple(cnt1[cnt1[:, :, 0].argmin()][0])  # cnt1[:, :, 0]是所有点的x坐标
# 2. 最右点:x坐标最大的点
rightmost = tuple(cnt1[cnt1[:, :, 0].argmax()][0])
# 3. 最上点:y坐标最小的点(图像y轴向下,所以y最小是最顶端)
topmost = tuple(cnt1[cnt1[:, :, 1].argmin()][0])
# 4. 最下点:y坐标最大的点
bottommost = tuple(cnt1[cnt1[:, :, 1].argmax()][0])# 绘制极值点(不同颜色的圆点)
cv2.circle(img1, leftmost, 5, (255, 0, 0), -1)    # 蓝色:最左
cv2.circle(img1, rightmost, 5, (0, 255, 0), -1)   # 绿色:最右
cv2.circle(img1, topmost, 5, (0, 0, 255), -1)     # 红色:最上
cv2.circle(img1, bottommost, 5, (255, 255, 0), -1)# 青色:最下# 标注极值点
cv2.putText(img1, 'Left', leftmost, cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1)
cv2.putText(img1, 'Right', rightmost, cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)cv2.imshow('Contour Extreme Points', img1)
cv2.waitKey(0)
cv2.destroyAllWindows()

2. 凸包与凸包缺陷(目标凹陷检测)

  • 凸包:包含轮廓的最小凸多边形(类似 “橡皮筋包裹目标”)。
  • 凸包缺陷:轮廓与凸包之间的凹陷区域(如手掌轮廓的指缝处),适用于手势识别、缺陷检测。
# 1. 计算凸包:returnPoints=False表示返回凸包顶点在原轮廓中的索引(用于后续缺陷计算)
hull = cv2.convexHull(cnt1, returnPoints=False)# 2. 计算凸包缺陷:需先判断轮廓是否为凸形
is_convex = cv2.isContourConvex(cnt1)
print(f'Is the contour convex? {is_convex}')if not is_convex and len(hull) > 3:  # 非凸轮廓且凸包顶点≥3才存在缺陷defects = cv2.convexityDefects(cnt1, hull)  # 缺陷列表,每个缺陷含4个参数:s,e,f,d# 遍历所有缺陷并绘制for i in range(defects.shape[0]):s, e, f, d = defects[i, 0]  # s:缺陷起始点索引,e:结束点索引,f:最远凹陷点索引,d:凹陷深度start = tuple(cnt1[s][0])    # 缺陷起始点end = tuple(cnt1[e][0])      # 缺陷结束点far = tuple(cnt1[f][0])      # 最远凹陷点# 绘制凸包(黄色)和缺陷(绿色线段连接起始/结束点,红色圆点标记凹陷点)cv2.drawContours(img1, [cv2.convexHull(cnt1)], 0, (0, 255, 255), 2)cv2.line(img1, start, end, (0, 255, 0), 2)cv2.circle(img1, far, 5, (0, 0, 255), -1)cv2.imshow('Convex Hull & Defects', img1)
cv2.waitKey(0)
cv2.destroyAllWindows()

3. 点与轮廓的关系(内外判断)

通过cv2.pointPolygonTest()判断一个点是否在轮廓内部、外部或边界上,返回值的含义:

  • :点在轮廓内部(值为点到轮廓的距离)。
  • :点在轮廓外部(值为距离的负值)。
  • 0:点在轮廓边界上。
# 测试点:假设两个点(可根据实际图像调整坐标)
test_point1 = (500, 500)  # 测试点1
test_point2 = (cx1, cy1)  # 测试点2(重心,应在内部)# 计算点与轮廓的关系
dist1 = cv2.pointPolygonTest(cnt1, test_point1, measureDist=True)  # measureDist=True返回距离
dist2 = cv2.pointPolygonTest(cnt1, test_point2, measureDist=True)# 绘制测试点并标注结果
def draw_test_point(img, point, dist):if dist > 0:color = (0, 255, 0)  # 绿色:内部label = f'Inside (dist: {dist:.1f})'elif dist < 0:color = (0, 0, 255)  # 红色:外部label = f'Outside (dist: {dist:.1f})'else:color = (255, 0, 0)  # 蓝色:边界label = 'On Contour'cv2.circle(img, point, 5, color, -1)cv2.putText(img, label, (point[0]+10, point[1]), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1)draw_test_point(img1, test_point1, dist1)
draw_test_point(img1, test_point2, dist2)cv2.imshow('Point-Polygon Relationship', img1)
cv2.waitKey(0)
cv2.destroyAllWindows()

五、形状匹配:判断两个轮廓的相似度

cv2.matchShapes()通过比较轮廓的Hu 矩(具有尺度、旋转、平移不变性的特征),计算两个轮廓的相似度,返回值越小,形状越相似(通常 < 0.1 认为是同一类形状),适用于目标识别(如零件分类、手写数字匹配)。

用户代码的最后一步就是形状匹配,以下是完整实现与结果解读:

# 形状匹配:cv2.matchShapes(轮廓1, 轮廓2, 匹配方法, 0)
# 匹配方法:1→cv2.CONTOURS_MATCH_I1,常用且鲁棒性较好
match_score = cv2.matchShapes(cnt1, cnt2, cv2.CONTOURS_MATCH_I1, 0.0)# 输出匹配结果并判断相似度
print(f'Shape Match Score: {match_score:.4f}')
if match_score < 0.1:print('Conclusion: The two shapes are highly similar!')
else:print('Conclusion: The two shapes are different.')# 可视化两个轮廓的对比
# 绘制第一张图的轮廓
cv2.drawContours(img1, [cnt1], 0, (0, 255, 0), 2)
cv2.putText(img1, f'Match Score: {match_score:.4f}', (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)# 绘制第二张图的轮廓
cv2.drawContours(img2, [cnt2], 0, (0, 255, 0), 2)
cv2.putText(img2, f'Match Score: {match_score:.4f}', (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)# 并排显示两张图
combined_img = np.hstack((img1, img2))  # 水平拼接图像
cv2.imshow('Shape Matching Comparison', combined_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

关键特性:Hu 矩具有尺度不变性(目标放大 / 缩小不影响)、旋转不变性(目标旋转不影响)、平移不变性(目标移动不影响),因此形状匹配不受目标的位置、大小和姿态影响。

总结:轮廓分析的典型流程与应用场景

1. 轮廓分析完整流程

  1. 预处理:彩色图→灰度图→二值化(阈值处理),确保前景目标与背景分离。
  2. 轮廓检测:用cv2.findContours()提取轮廓,选择合适的检索模式和逼近方法。
  3. 属性计算:重心(定位)、面积 / 周长(大小)、极值点(边界)。
  4. 形状拟合:多边形逼近(简化)、包围框 / 圆 / 椭圆(边界与姿态)。
  5. 结构分析:凸包与缺陷(凹陷检测)、点与轮廓关系(内外判断)。
  6. 形状匹配:用cv2.matchShapes()实现目标识别与分类。

2. 核心应用场景

技术模块应用场景
轮廓检测与属性工业零件尺寸测量(面积、周长、直径)
重心与包围框机器人目标抓取(定位目标中心与边界)
凸包缺陷手势识别(检测指缝)、产品缺陷检测(凹陷)
形状匹配零件分类、手写数字识别、目标检索

通过掌握轮廓分析的全套技术,可解决计算机视觉中 “目标在哪里、是什么形状、有多大、是否与模板一致” 等核心问题,是实现工业检测、智能识别等任务的基础。

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

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

相关文章

2025最新uni-app横屏适配方案:微信小程序全平台兼容实战

以下为uni-app实现微信小程序横屏适配技术方案&#xff0c;包含核心原理、配置方法、代码示例和注意事项&#xff1a;一、横屏适配原理 微信小程序默认采用竖屏模式&#xff0c;横屏适配需通过以下机制实现&#xff1a; 全局配置&#xff1a;在app.json中声明支持横屏页面级配置…

深入解析Nginx常见模块1

在Web服务器和反向代理服务器领域,Nginx凭借其高性能、稳定性和丰富的功能获得了广泛的应用。本文将介绍一些Nginx中常见的模块,帮助你更好地理解和使用它们。 Nginx模块简介 Nginx的模块系统是其强大功能的核心所在,它允许用户根据需要灵活配置服务器的行为。Nginx的模块大…

浅谈new与::operator new

目录 前言 1.为什么C要引入new/delete&#xff1f; 2.operator new与operator delete函数 它们的实际作用 Placement New&#xff08;定位new表达式&#xff09; 总结 前言 在写上一篇博客“vector的模拟实现”时&#xff0c;我一直很好奇vector的private成员为什么要用三个封…

Java中Integer转String

在 Java 中&#xff0c;将 Integer 转换为 String 有多种方法&#xff0c;以下是常见的几种方式&#xff1a;1. 使用 Integer.toString() 方法javaInteger num 123; String str Integer.toString(num); // 直接调用 Integer 的静态方法2. 使用 String.valueOf()javaInteger n…

智能装备如何与软件结合?

一、什么是智能装备&#xff1f; 智能装备是具备“感知-决策-执行-自适应”闭环能力的智能化系统&#xff0c;本质是“传统物理装备”与“数字智能”的深度融合。它不仅能完成预设动作&#xff08;如传统机械臂焊接&#xff09;&#xff0c;还能通过传感器“观察”环境、用算法…

react性能优化有哪些

React 性能优化的手段比较多&#xff0c;既有代码层面的&#xff0c;也有构建层面的&#xff0c;还涉及到运行时调优。我帮你系统性梳理一份&#xff1a;&#x1f539; 一、渲染性能优化1. 减少不必要的渲染React.memo&#xff1a;对函数组件做浅比较&#xff0c;避免相同 prop…

腾讯云OpenCloudOS 9系统部署OpenTenBase数据库详细教程

OpenTenBase简介OpenTenBase是一个关系型数据库集群平台&#xff0c;提供写入可靠性和多节点数据同步功能。可以在一台或多台主机上配置OpenTenBase&#xff0c;并将数据存储在多个物理主机上。OpenTenBase架构组件&#xff1a;Coordinator Node (CN)&#xff1a;应用程序访问入…

【计算机视觉】Pixel逐像素分类Mask掩码分类理解摘要

目标检测和实例分割是计算机视觉的基本任务。目标检测的传统方法中通常利用边界框技术进行对象定位&#xff0c;然后利用逐像素分类为这些本地化实例分配类。但是当处理同一类的重叠对象时&#xff0c;或者在每个图像的对象数量不同的情况下&#xff0c;这些方法通常会出现问题…

C++之stack类的代码及其逻辑详解

1. stack介绍及使用方法stack是一种后进先出的数据结构&#xff0c;所以在C的STL库中也同样遵循了这一点&#xff0c;我们在使用的时候不支持随机访问或迭代器遍历。注意事项调用 top() 或 pop() 前需确保栈非空&#xff0c;否则可能引发未定义行为。stack 没有 clear() 函数&a…

Spring Cache实现简化缓存功能开发

一. 介绍Spring Cache 是 Spring 框架提供的缓存抽象层&#xff0c;它简化了在应用中添加缓存功能的开发工作。通过 Spring Cache&#xff0c;开发者无需关注具体缓存实现的细节&#xff0c;只需通过注解就能快速实现方法级别的缓存管理。核心特点1. 与具体缓存实现解耦&#x…

Lombok(简化Java当中的开发)

Lombok概述 以前的Java项目中,充斥着太多不友好的代码:POJO的getter/setter/toString/构造方法;打印日志;I/O流的关闭操作等等,这些代码既没有技术含量,又影响着代码的美观,Lombok应运而生。 LomBok可以通过注解,帮助开发人员消除JAVA中尤其是POJO类中的冗长代码。 使…

【DeepSeek】公司内网部署离线deepseek+docker+ragflow本地模型实战

企业内部可能有些数据比较敏感&#xff0c;不能连接互联网。本次实验操作是将deepseek完全离线后迁移至内网使用&#xff0c;实验基于Windows server 2022 datacenter系统安装deepseek、docker、ragflow。 目录使用VMware新建WIN2022虚拟机一、安装DeepSeek模型二.安装Docker使…

【软考架构】面向服务的体系结构(SOA)深度解析

面向服务的体系结构&#xff08;SOA&#xff09;深度解析 面向服务的体系结构&#xff08;Service-Oriented Architecture, SOA&#xff09;是一种以服务为核心的软件架构范式&#xff0c;通过标准化接口实现异构系统间的高效集成与协作。以下从概念定义、发展脉络、技术演进、…

centos7中MySQL 5.7.32 到 5.7.44 升级指南:基于官方二进制包的原地替换式升级

目录前言1. 升级概述1.1 升级背景1.2 升级目的1.3 升级方法概述1.4 升级策略与注意事项2. 升级准备2.1 备份工作2.2 下载目标版本2.3 停止 MySQL 服务3. 替换二进制文件3.1 解压官方二进制包3.2 替换核心二进制文件3.3 更新共享库4. 执行升级并验证4.1 启动 MySQL 服务4.2 监控…

数学七夕花礼(MATLAB版)

前言参考的视频在抖音&#xff0c;电脑版的抖音一直登录不了&#xff0c;用手机分享的链接如下所示。4.35 Iv.FH yTl:/ 04/04 复制打开抖音&#x1f440;数学送的七夕花礼&#xff0c;记得查收噢.# 七夕花礼请查收 ... https://v.douyin.com/H-YpOJCyQyg/rho4sin(8theta)公式&a…

LeetCode - 21. 合并两个有序链表

题目 21. 合并两个有序链表 思路 我会采用双指针的方法&#xff0c;同时遍历两个链表&#xff0c;比较当前节点的值&#xff0c;将较小的节点添加到结果链表中。 具体思路是这样的&#xff1a; 首先创建一个哑节点(dummy node)作为合并后链表的头部&#xff0c;这样可以简…

ES01-环境安装

ES01-环境安装 文章目录ES01-环境安装1-参考网址2-知识总结1-参考网址 elasticsearch官网地址&#xff1a;https://www.elastic.co/安装elasticsearch9.0.0参考&#xff1a;https://zhuanlan.zhihu.com/p/1920780524991017021安装elasticsearch9.0.0参考&#xff1a;http://ww…

UI前端大数据可视化实战策略:如何设计符合用户认知的数据可视化界面?

hello宝子们...我们是艾斯视觉擅长ui设计、前端开发、数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩!UI前端大数据可视化实战策略&#xff1a;如何设计符合用户认知的数据可视化界面&#xff1f;数…

学习python第15天

其实前面学的根本不记得了&#xff0c;小丑.jpg&#xff0c;如果真的面试问到了估计也是一脸懵今日任务&#xff1a;JSON先认识一下JSON和JSONL文件记得之前在面试KIMI的时候&#xff0c;面试官就给我出了JSONL和EXCEL转换的手撕代码题&#xff0c;而那个时候&#xff0c;我连什…

Spring框架集成Kakfa的方式

Spring框架集成Kakfa的方式 springboot集成kafka的方式 添加maven依赖 <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.0</version> </dependency&g…