Opencv高级图像处理

文章目录

Opencv高级图像处理

图像坐标

在这里插入图片描述

row=height=Point.y
col=width=Point.x

二值化

import cv2  
import numpy as np  # 打开图像  
image_path = 'your_image_path.jpg'  # 图片路径  
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)  # 以灰度模式读取图像  # 检查图像是否正确读取  
if image is None:  print(f"Could not open or find the image: {image_path}")  exit(0)  # 选择二值化方法,这里使用简单的阈值法  
# 你可以调整阈值(127, 255)来得到不同的效果  
# 第一个参数是源图像,第二个参数是用于分类像素的阈值,  
# 第三个参数是赋予超过阈值的像素的新值,第四个参数是二值化的类型  
ret, binary_image = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)  # 保存处理后的图像  
output_path = 'binary_image.jpg'  # 保存路径
cv2.imwrite(output_path, binary_image)

滤波

高斯滤波

blurred = cv2.GaussianBlur(image, (11, 11), 0)

中值滤波

result = cv2.medianBlur(image, 3)

开闭运算

op_open = cv2.morphologyEx(blurred_raw, cv2.MORPH_OPEN, k) # 开运算
op_close = cv2.morphologyEx(blurred_raw, cv2.MORPH_CLOSE, k) # 闭运算

检测

霍夫圆检测

函数 cv2.HoughCircles()

参数含义
image原始图像
method目前只支持cv2.HOUGH_GRADIENT
dp图像解析的反向比例。1为原始大小,2为原始大小的一半
minDist圆心之间的最小距离。过小会增加圆的误判,过大会丢失存在的圆
param1(maxval)Canny检测器的高阈值,用于检测边缘点的阈值,大于此值才被检测出来。
param2(minval)检测阶段圆心的累加器阈值(thresh)。越小的话,会增加不存在的圆;越大的话,则检测到的圆就更加接近完美的圆形,检测到圆所需要的最小边缘点数,边缘点数小于此值则舍弃。
minRadius检测的最小圆的半径
maxRadius检测的最大圆的半径
# 霍夫圆检测
circles = cv2.HoughCircles(image=raw, cv2.HOUGH_GRADIENT, dp=1, minDist=20, param1=150, param2=100,minRadius=0, maxRadius=0)# 绘制检测圆
if circles is not None:print(f"检测到圆的个数:{len(circles)}")# print(f"{circles}")circles = np.round(circles[0, :]).astype("int")for (x, y, r) in circles:cv2.circle(image, (x, y), r, (0, 255, 0), 1)
else:print("未检测到圆")

边缘检测

Canny边缘检测
  • 目的:Canny边缘检测算法的目的是识别图像中的一维边缘。该算法通过多步骤过程检测图像中的边缘,包括平滑图像以减少噪声、计算图像梯度以找到潜在的边缘点、应用非极大值抑制(NMS)以获得细边缘,以及使用双阈值算法和边缘连接通过滞后阈值处理确定最终边缘。
  • 输出:Canny算法输出的是一个二值图像,其中边缘上的像素为白色(或1),其余像素为黑色(或0)。

在这里插入图片描述

edges = cv2.Canny(blurred_raw, threshold1=10, threshold2=70)
# edges 是检测之后的图像

原理:参考链接:知乎文章

findContours
  • 目的findContours函数的目的是从二值图像中提取轮廓线。轮廓可以被视为连续的点(沿着边界)组成的曲线,适用于形状分析和对象检测和识别。
  • 工作方式findContours通过追踪二值图像中的白色(或前景)部分的边缘来查找轮廓。这通常是在应用了阈值处理或边缘检测之后进行。
  • 输出:该函数返回两个主要的输出:轮廓本身(一个点的列表,这些点连续地定义了边界)和每个轮廓的层级信息(表示轮廓之间的父子关系)。
# 边缘检测
ret, thresh = cv2.threshold(src=blurred_image, thresh=60, maxval=255, type=0)
contours, hierarchy = cv2.findContours(image=thresh, mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_SIMPLE)# image,单通道图像矩阵,可以是灰度图,但更常用的是二值图像,一般是经过Canny、拉普拉斯等边缘检测算子处理过的二值图像# 绘制边缘
image = cv2.drawContours(image=image, contours=contours, contourIdx=-1, color=(0, 255, 0), thickness=3)
区别
  • 应用场景:Canny边缘检测主要用于边缘识别,适合于图像中边缘的检测和跟踪。而findContours用于提取轮廓信息,适用于更高级的形状分析和对象识别。
  • 输出类型:Canny边缘检测输出一个二值图像,其中包含检测到的边缘。findContours则返回轮廓点的集合,这些点可以用来描述对象的形状。
  • 后续处理:Canny检测出的边缘通常用作其他图像处理操作的预处理步骤,比如轮廓提取。findContours通常是形状分析或对象识别流程中的一步,它依赖于边缘检测的结果。

简而言之,Canny边缘检测专注于识别图像中的边缘,而findContours则用于基于这些边缘或其他图像特征提取和分析轮廓。在许多实际应用中,这两个步骤经常连续使用:首先应用Canny边缘检测来找到边缘,然后使用findContours来提取这些边缘形成的轮廓。

傅里叶变换-高/低通滤波

使用傅里叶变换进行高/低通滤波。

import cv2  
import numpy as np  
from matplotlib import pyplot as plt  def fourier_filter(image_path, output_path_lowpass, output_path_highpass, d0):  # 读取图像  img = cv2.imread(image_path, 0)  # 进行傅里叶变换  dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)  dft_shift = np.fft.fftshift(dft)  # 创建低通和高通滤波器掩模  rows, cols = img.shape  crow, ccol = rows // 2, cols // 2  mask_lowpass = np.zeros((rows, cols, 2), np.uint8)  mask_highpass = np.ones((rows, cols, 2), np.uint8)  r = d0 // 2  center = [crow, ccol]  x, y = np.ogrid[:rows, :cols]  mask_area_lowpass = (x - center[0]) ** 2 + (y - center[1]) ** 2 <= r*r  mask_lowpass[mask_area_lowpass] = 1  mask_highpass[mask_area_lowpass] = 0  # 应用滤波器并进行逆DFT  fshift_lowpass = dft_shift * mask_lowpass  fshift_highpass = dft_shift * mask_highpass  f_ishift_lowpass = np.fft.ifftshift(fshift_lowpass)  f_ishift_highpass = np.fft.ifftshift(fshift_highpass)  img_back_lowpass = cv2.idft(f_ishift_lowpass)  img_back_highpass = cv2.idft(f_ishift_highpass)  img_back_lowpass = cv2.magnitude(img_back_lowpass[:, :, 0], img_back_lowpass[:, :, 1])  img_back_highpass = cv2.magnitude(img_back_highpass[:, :, 0], img_back_highpass[:, :, 1])  # 归一化到0-255并保存结果  img_back_lowpass = cv2.normalize(img_back_lowpass, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)  img_back_highpass = cv2.normalize(img_back_highpass, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)  # 保存图像  cv2.imwrite(output_path_lowpass, img_back_lowpass)  cv2.imwrite(output_path_highpass, img_back_highpass)  # 显示图像(可选)  plt.subplot(131), plt.imshow(img, cmap='gray'), plt.title('Input Image')  plt.subplot(132), plt.imshow(img_back_lowpass, cmap='gray'), plt.title('Lowpass Filter')  plt.subplot(133), plt.imshow(img_back_highpass, cmap='gray'), plt.title('Highpass Filter')  plt.show()  # 使用示例:  
image_path = 'path_to_your_image.jpg'  # 请替换为你的图像文件路径  
output_path_lowpass = 'output_lowpass.jpg'  # 低通滤波后的输出文件路径  
output_path_highpass = 'output_highpass.jpg'  # 高通滤波后的输出文件路径  
d0 = 60  # 滤波器的直径,可根据需要调整  
fourier_filter(image_path, output_path_lowpass, output_path_highpass, d0)

直线检测

# 将彩色图片灰度化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray,(11, 11), 0)
# 进行Hough_line直线检测
lines = cv2.HoughLines(edges, 1, np.pi / 180, 240)
print(len(lines))
print(lines)

在这里插入图片描述

直线的绘制

# 遍历每一个r和theta
for i in range(len(lines)):r, theta = lines[i, 0, 0], lines[i, 0, 1]a = np.cos(theta)  # cos(theta)b = np.sin(theta)  # sin(theta)x0 = a * r  # rcos(theta)y0 = b * r  # rsin(theta)x1 = int(x0 + 1000 * (-b))  # rcos(theta)-1000sin(theta)y1 = int(y0 + 1000 * (a))  # rsin(theta)+1000cos(theta)x2 = int(x0 - 1000 * (-b))  # rcos(theta)+1000sin(theta)y2 = int(y0 - 1000 * (a))  # rsin(theta)-1000cos(theta)cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 1)  # 绘制直线结果

相机标定

**相机标定的主要作用和目的是为了提高机器视觉系统在三维测量和识别中的应用精度。**具体来说,相机标定可以解决以下问题:

  1. 被测平面不确定性:在实际应用中,被测平面的位置可能无法精确控制,而且镜头也不是理想的小孔模型,因此无法直接使用简单的公式计算实际距离。
  2. 镜头畸变:镜头可能存在畸变,这会影响图像的正确性,使得无法直接使用小孔成像模型来计算距离。
  3. 非理想坐标平面转换:在三维空间中,需要将任意坐标平面转换到理想坐标平面上,并对有畸变的图像进行校正,以便进行后续的尺寸和位置测量。

通过相机标定,可以确定相机的内参和外参,包括镜头的焦距、畸变参数、光轴中心坐标和像元尺寸等。这些参数是唯一确定的,当摄像机和镜头确定时。通过这些参数的转换和校正,可以实现对三维空间中任意平面上尺寸与位置的测量,从而提高机器视觉系统的测量和定位精度。

# 相机标定
retval, cameraMatrix, distCoeffs, rvecs, tvecs = cv2.calibrateCamera(objectPoints, imagePoints, imageSize)

参数

retval:标定误差

cameraMatrix: 内在相机矩阵

distCoeffs: 镜头畸变系数。

rvecs: 为 3×1 旋转向量。向量的方向指定旋转轴,向量的大小指定旋转角度。

tvecs: 3×1 平移向量。

校准因素

import cv2
import numpy as np
import globdef main():# 参数设置criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)w, h = 11, 8  # 棋盘格内角点数量(亲自数)objp = np.zeros((w * h, 3), np.float32)objp[:, :2] = np.mgrid[0:w, 0:h].T.reshape(-1, 2)# 存储角点信息objpoints = []  # 三维世界坐标imgpoints = []  # 二维图像坐标# 加载并处理图像images = glob.glob('data/d2/*.jpg')for fname in images:img = cv2.imread(fname)# img = cv2.resize(img, (768, 1024))  # 统一图像大小gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# gray = cv2.GaussianBlur(gray, (11, 11), 0)  # 滤波处理# 寻找棋盘格角点ret, corners = cv2.findChessboardCorners(gray, (w, h), None)if ret:corners = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)  # 亚像素级角点检测m = [c[0] for c in corners]passobjpoints.append(objp)imgpoints.append(corners)# 可视化和保存结果cv2.drawChessboardCorners(img, (w, h), corners, True)cv2.imshow('Corners Found', img)cv2.waitKey(100)# 根据需要保存图像,这里以序号命名cv2.imwrite(f"result/mm_{len(imgpoints)}.jpg", img)else:print(f"Calibration failed for image: {fname}")cv2.destroyAllWindows()# 相机标定ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, (768, 1024), None, None)# 输出标定结果print("Calibration Error:", ret)print("Intrinsic Matrix:\n", mtx)print("Distortion Coefficients:\n", dist.ravel())# 如果需要,可以保存或进一步处理旋转向量和平移向量# print("Rotation Vectors:\n", rvecs)# print("Translation Vectors:\n", tvecs)if __name__ == '__main__':main()

详细阅读:参考链接

视频处理

视频格式

code ={"mp4":"mp4v","avi":"I420","flv":"FLV1"}cv2.VideoWriter_fourcc('I','4','2','0') 
# 这个选项是一个未压缩的YUV编码,4:2:0色度子采样。这种编码广泛兼容,但会产生大文件。文件扩展名应为.avi。cv2.VideoWriter_fourcc('P','I','M','1')
# 此选项为MPEG-1。文件扩展名应为.avi。cv2.VideoWriter_fourcc('X','V','I','D') 
# 此选项是一个相对较旧的MPEG-4编码。如果要限制结果视频的大小,这是一个很好的选择。文件扩展名应为.avi。cv2.VideoWriter_fourcc('M','J','P','G')
# 此选项为motion-jpeg视频。文件扩展名应为.avi。cv2.VideoWriter_fourcc('X','2','6','4'):
# 这个选项是一种比较新的MPEG-4编码方式。如果你想限制结果视频的大小,这可能是最好的选择。文件扩展名应为.mp4。cv2.VideoWriter_fourcc('H','2','6','4'):
# 这个选项是传统的H264编码方式。如果你想限制结果视频的大小,这可能是很好的选择。文件扩展名应为.mp4。cv2.VideoWriter_fourcc('m', 'p', '4', 'v') 
# 此选项是另一个相对较旧的MPEG-4编码。如果要限制结果视频的大小,这是一个很好的选择。文件扩展名应为.m4v。cv2.VideoWriter_fourcc('T','H','E','O') 
# 这个选项是Ogg Vorbis。文件扩展名应为.ogv。cv2.VideoWriter_fourcc('F','L','V','1')
# 此选项为Flash视频。文件扩展名应为.flv。

模板

摄像头处理(带参调节)

import cv2
import tracebackdef callback(value):print(value)def detect(img, k_size, min_val, max_val):return imgif __name__ == '__main__':h = BaslerCam(szSettingFile='xxx.pfs', szName='Test_use_01')cv2.namedWindow("img")cv2.resizeWindow("img", (1024, 768))cv2.createTrackbar("k_size", "img", 10, 90, callback)cv2.createTrackbar("c_minval", "img", 10, 90, callback)cv2.createTrackbar("c_maxval", "img", 10, 90, callback)base_size = 10base_minval = 10base_maxval = 10while True:b, hFrames = h.ReadFrames(1)try:if len(hFrames) == 0:continuep = hFrames[0]try:k_size = cv2.getTrackbarPos("k_size", "img")k_size = k_size if k_size % 2 == 1 else k_size + 1c_minval = cv2.getTrackbarPos("c_minval", "img")c_maxval = cv2.getTrackbarPos("c_maxval", "img")result = detect(p.copy(), (base_size + k_size, base_size + k_size), base_minval + c_minval,base_maxval + c_maxval)  # 保存结果if result is not None:cv2.imshow("img", cv2.resize(result, (1024, 768)))cv2.waitKey(1)except Exception as e:traceback.print_exc()except Exception as e:print(e)traceback.print_exc()

单图片处理(带参调节)

import cv2
import tracebackdef callback(value):print(value)def detect(img, k_size, min_val, max_val):return imgif __name__ == '__main__':img_path = "../data/result/img/1712817408432.jpg"# 读取输入图片data/resource/img/led/1711702476703.jpgimg = cv2.imread(img_path)img = cv2.resize(img, (1024, 768))cv2.namedWindow("img")cv2.resizeWindow("img", (1024, 768))cv2.createTrackbar("k_size", "img", 10, 90, callback)cv2.createTrackbar("c_minval", "img", 10, 90, callback)cv2.createTrackbar("c_maxval", "img", 10, 90, callback)base_size = 10base_minval = 10base_maxval = 10while True:try:k_size = cv2.getTrackbarPos("k_size", "img")k_size = k_size if k_size % 2 == 1 else k_size + 1c_minval = cv2.getTrackbarPos("c_minval", "img")c_maxval = cv2.getTrackbarPos("c_maxval", "img")result = detect(img.copy(), (base_size + k_size, base_size + k_size), base_minval + c_minval,base_maxval + c_maxval)# 保存结果# file_name = img_path.split("/")[-1]# print(file_name)# cv2.imwrite(f"../data/result/img/r_{file_name}", result)if result is not None:cv2.imshow("img", result)cv2.waitKey(1)except Exception as e:print(e)traceback.print_exc()

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

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

相关文章

MFC绘制哆啦A梦

OnPaint绘制代码 CPaintDC dc(this); // 用于绘画的设备上下文CRect rc;GetWindowRect(rc);int cxClient rc.Width();int cyClient rc.Height();// 辅助线HPEN hPen CreatePen(PS_DOT, 1, RGB(192, 192, 192));HPEN hOldPen (HPEN)SelectObject(dc, hPen);MoveToEx(dc, cxC…

EasyCVR/EasyDSS无人机直播技术助力野生动物监测:开启野生动物保护新篇章

近日有新闻报道&#xff0c;一名挖掘机师傅在清理河道时&#xff0c;意外挖出一只稀有的扬子鳄&#xff0c;挖机师傅小心翼翼地将其放在一边&#xff0c;扬子鳄也顺势游回一旁的河道中。 随着人类对自然环境的不断探索和开发&#xff0c;野生动物及其栖息地的保护显得愈发重要。…

ROS(四)

write in advance 实验四&#xff0c;在经历了实验三的失败后&#xff0c;卷土重来。 幸运的是&#xff0c;此次实验很简单&#xff0c;很快就能搞定。 Part one 使用指令查看自己摄像头的设备号&#xff0c;如果报错&#xff0c;且你为虚拟机&#xff0c;可能是未在虚拟机处…

Elasticsearch docker 安装及基本用法

创建网络 首先通过命令创建一个网络 docker network create es-net然后查看网络 [rootDocker ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 4e315f5e3ae7 bridge bridge local a501a9f3b4ee es-net bridge local ebca66b02e8c host …

修改文件的权限(linux篇)

1.在yl用户下创建一个demo.txt文件 [rootlocalhost ~]# su yl [yllocalhost root]$ cd [yllocalhost ~]$ cd Desktop/ [yllocalhost Desktop]$ ls [yllocalhost Desktop]$ vim demo.txt 填入一些信息进行保存 2.查看文件信息以及所对应的组 [yllocalhost Desktop]$ ll 总用量…

MYSQL 四、mysql进阶 1(mysql逻辑架构以及查询流程)

一、mysql的逻辑架构 1. 逻辑架构剖析 1.1 服务器处理客户端请求 mysql是典型的c/s架构&#xff0c;即 client/server 架构&#xff0c;不论是客户端进程和服务器进程是采用哪种方式进行通信&#xff0c;最后实现的效果都是&#xff1a;客户端进程向服务器进程发送一段文本&am…

MySQL 创建数据表

创建MySQL数据表需要以下信息&#xff1a; 表名表字段名定义每个表字段 语法 以下为创建MySQL数据表的SQL通用语法&#xff1a; CREATE TABLE table_name (column_name column_type); 以下例子中我们将在 W3CSCHOOL 数据库中创建数据表w3cschool_tbl&#xff1a; CREAT…

大数据集群离线解析经纬度逆编码地址

背景 最近有个需要需求把经纬度解析为地址&#xff0c;那么通常解析地址市面上流行的方案就是调取百度、高德地图的接口进行解析。 难点 但是在用这个方案遇到一个问题就是企业认证的百度地图每天的逆编码解析为300w次&#xff0c;qps为100次/秒&#xff0c;对于日增上千万的…

Golang | Leetcode Golang题解之第166题分数到小数

题目&#xff1a; 题解&#xff1a; func fractionToDecimal(numerator, denominator int) string {if numerator%denominator 0 {return strconv.Itoa(numerator / denominator)}s : []byte{}if numerator < 0 ! (denominator < 0) {s append(s, -)}// 整数部分numer…

springboot 3.x 之 集成rabbitmq实现动态发送消息给不同的队列

背景 实际项目中遇到针对不同类型的消息&#xff0c;发送消息到不同的队列&#xff0c;而且队列可能还不存在&#xff0c;需要动态创建&#xff0c;于是写了如下代码&#xff0c;实践发现没啥问题&#xff0c;这里分享下。 环境 springboot 3.2 JDK 17 rabbitMQ模型介绍 图片…

TwinCAT3 Scope Y-T NC Project的使用方法(电机参数监控时序图)

TwinCAT3 Scope Y-T NC Project的使用方法 图中有两个电机 在程序中添加两个电机轴 右键点击解决方案&#xff0c;然后添加Scope YT Project 记录绝对位置&#xff0c;速度&#xff0c;相对位置&#xff0c;加速度&#xff0c;跟随误差 如果不是本地的虚拟轴&#xff0c;则可以…

OpenCV中的圆形标靶检测——findCirclesGrid()(二)

本章我们开始讲解基于层次聚类的标靶检测算法。当我们调用如下API,且flags中包含cv::CALIB_CB_CLUSTERING标志位时,将会执行基于层次聚类的斑点检测算法。算法支持对称标靶和非对称标靶两类,相应的需要将下述flags设为包含CALIB_CB_SYMMETRIC_GRID或CALIB_CB_ASYMMETRIC_GRI…

JVM性能优化工具及问题排查

jvm性能优化工具 jdk提供给我们了很实用的工具来分析JVM的状态&#xff0c;线程以及配置&#xff0c;这些工具包含于jdk中&#xff0c;并且以java实现&#xff0c;是JVM性能优化必不可少的工具集&#xff0c;这些工具都在$JAVA_HOME/bin下 jps、jinfo、jstack、jmap、jstat基本…

打开nginx连接的php页面报错502

目录 问题描述&#xff1a; 原因&#xff1a; 1. 使用 Unix 域套接字&#xff08;Unix Socket&#xff09; 区别和优势&#xff1a; 2. 使用 TCP/IP 套接字 区别和优势&#xff1a; 如何选择 扩展&#xff1a;Rocky_Linux9.4安装PHP的步骤&#xff1a; 使用Remi存储库…

NLP入门——基于梯度下降法分类的应用

问题分析 我们前面研究的都是基于统计的方法&#xff0c;通过不同的统计方法得到不同的准确率&#xff0c;通过改善统计的方式来提高准确率。现在我们要研究基于数学的方式来预测准确率。 假设我们有一个分词 s_{class,word}&#xff0c;class是该对象的类别&#xff0c;word…

【漏洞复现】金和OA C6 download.jsp 任意文件读取漏洞

免责声明&#xff1a; 本文内容旨在提供有关特定漏洞或安全漏洞的信息&#xff0c;以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步&#xff0c;并非出于任何恶意目的。阅读者应该明白&#xff0c;在利用本文提到的漏洞信息或进行相关测…

AI数据分析:Excel表格智能判断数据起点来计算增长率

工作任务&#xff1a;计算Excel表格中2023年1月到2024年4月的总增长率和复合增长率。 如果数据都有的情况下&#xff0c;公式很简单&#xff1a; 总增长率 (O2-B2)/B2 复合增长率 POWER((O2/B2),1/13)-1 但是&#xff0c;2023年1月、2月、3月的数据&#xff0c;有些有&…

AI办公自动化:用通义千问批量翻译长篇英语TXT文档

在deepseek中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;现在要完成一个编写基于qwen-turbo模型API和dashscope库的程序脚本&#xff0c;具体步骤如下&#xff1a; 打开文件夹&#xff1a;F:\AI自媒体内容\待翻译&#xff1b; 获取里面所有TXT文档&#xff…

mac如何检测硬盘损坏 常用mac硬盘检测坏道工具推荐

mac有时候也出现一些问题&#xff0c;比如硬盘损坏。硬盘损坏会导致数据丢失、系统崩溃、性能下降等严重的后果&#xff0c;所以及时检测和修复硬盘损坏是非常必要的。那么&#xff0c;mac如何检测硬盘损坏呢&#xff1f;有哪些常用的mac硬盘检测坏道工具呢&#xff1f; 一、m…

Python 数据可视化 散点图

Python 数据可视化 散点图 import matplotlib.pyplot as plt import numpy as npdef plot_scatter(ref_info_dict, test_info_dict):# 绘制散点图&#xff0c;ref横&#xff0c;test纵plt.figure(figsize(80, 48))n 0# scatter_header_list [peak_insert_size, median_insert…