语义分割miou指标计算详解

文章目录

    • 1. 语义分割的评价指标
    • 2. 混淆矩阵计算
      • 2.1 np.bincount的使用
      • 2.2 混淆矩阵计算
    • 3. 语义分割指标计算
      • 3.1 IOU计算
        • 方式1(推荐)
        • 方式2
      • 3.2 Precision 计算
      • 3.3 总体的Accuracy计算
      • 3.4 Recall 计算
      • 3.5 MIOU计算
    • 参考

MIoU全称为Mean Intersection over Union,平均交并比。可作为语义分割系统性能的评价指标。

  • P:Prediction预测值
  • G:Ground Truth真实值
    在这里插入图片描述
    其中IOU: 交并比就是该类的真实标签和预测值的交和并的比值
    在这里插入图片描述
    单类的交并比可以理解为下图:
    在这里插入图片描述

1. 语义分割的评价指标

True Positive (TP): 把正样本成功预测为正。
True Negative (TN):把负样本成功预测为负。
False Positive (FP):把负样本错误地预测为正。
False Negative (FN):把正样本错误的预测为负。

  • (1) Accuracy准确率,指的是“预测正确的样本数÷样本数总数”。计算公式为:
    A c c u r a c y = T P + T N T P + T N + F P + F N Accuracy = \frac{TP+TN}{TP+TN+FP+FN} Accuracy=TP+TN+FP+FNTP+TN

  • (2) Precision精确率或者精度,指的是预测为Positive的样本,占所有预测样本的比率
    P r e c i s i o n = T P T P + F P Precision= \frac{TP}{TP+FP} Precision=TP+FPTP

  • (3)Recall召回率,指的是预测为Positive的样本,占所有Positive样本的比率
    P r e c i s i o n = T P P Precision= \frac{TP}{P} Precision=PTP

  • (4) F1 score: 综合考虑了precisionrecall两方面的因素,做到了对于两者的调和,即:既要“求精”也要“求全”,做到不偏科。

F 1 s c o r e = 2 ∗ p r e c i s i o n ∗ r e c a l l p r e c i s i o n + r e c a l l F1 score= \frac{2*precision*recall}{precision+recall} F1score=precision+recall2precisionrecall

  • (5) MIOU 作为为语义分割最重要标准度量。其计算两个集合的交集和并集之比,在语义分割的问题中,这两个集合为真实值和预测值。在每个类上计算IoU,之后平均。计算公式如下
    M I O U = 1 k + 1 ∑ i = 0 k T P F N + F P + T P MIOU =\frac{1}{k+1}\sum_{i=0}^{k}\frac{TP}{FN+FP+TP} MIOU=k+11i=0kFN+FP+TPTP
    等价于:
    M I O U = 1 k + 1 ∑ i = 0 k p i i ∑ j = 0 k p i j + ∑ j = 0 k p j i − p i i MIOU=\frac{1}{k+1}\sum_{i=0}^{k}\frac{p_{ii}}{\sum_{j=0}^k p_{ij} + \sum_{j=0}^k p_{ji} -p_{ii}} MIOU=k+11i=0kj=0kpij+j=0kpjipiipii

其中: p i i p_{ii} pii 真实为类别i,预测也为i的像素个数,也就是正确预测的像素个数TP; p i j p_{ij} pij表示真实为类别i,但预测为类别j的像素个数,也就是FN p j i p_{ji} pji表示真实为类别j,但预测为类别i的像素个数, 也就是FP

注意: 对于多分类TN为0 ,即没有所谓的负样本

2. 混淆矩阵计算

  • 计算MIoU,我们需要借助混淆矩阵来进行计算。
  • 混淆矩阵就是统计分类模型的分类结果,即:统计归对类,归错类的样本的个数,然后把结果放在一个表里展示出来,这个表就是混淆矩阵
  • 每一列代表预测值(pred)每一行代表的是实际的类别(gt)
    在这里插入图片描述
  • 对角都对TP,横看真实,竖看预测: 每一行之和,为该行对应类(如Cat)的总数;每一列之和为该列对应类别的预测的总数。

2.1 np.bincount的使用

在计算混淆矩阵时,可以利用np.bincount函数方便我们计算。

numpy.bincount(x, weights=None, minlength=None)
  • 该方法返回每个索引值在x中出现的次数
  • 给一个向量x,x中最大的元素记为j,返回一个向量1行j+1列的向量y,y[i]代表i在x中出现的次数
#x中最大的数为7,那么它的索引值为0->7
x = np.array([0, 1, 1, 3, 2, 1, 7])
#索引0出现了1次,索引1出现了3次......索引5出现了0次......
np.bincount(x)
#因此,输出结果为:array([1, 3, 1, 1, 0, 0, 0, 1])
  • minlength也是一个常用的参数,表示输出的数组长度至少为minlength,如果x中最大的元素加1大于数组长度,那么数组的长度以x中最大元素加1为准(例如,如果数组中最大元素为3,minlength=5,那么数组的长度为5;如果数组中最大元素为7,minlength=5,那么数组的最大长度为7+1=8,这里之所以加1是因为元素0也占了一个索引)。举个例子说明:
# a中最大的数为3,因此数组长度为4,那么它的索引值为0->3
a = np.array([2, 2, 1, 3 ])
# 本来数组的长度为4,但指定了minlength为7,因此现在数组长度为7(多的补0),所以现在它的索引值为0->6
np.bincount(x, minlength=7)
# 输出结果为:array([0, 1, 2, 1, 0, 0, 0])# a中最大的数为4,因此bin的数量为5,那么它的索引值为0->4
x = np.array([4, 2, 3, 1, 2])
# 数组的长度原本为5,但指定了minlength为1,因为5 > 1,所以这个参数不起作用,索引值还是0->4
np.bincount(x, minlength=1)
# 输出结果为:array([0, 1, 2, 1,1])

2.2 混淆矩阵计算

# 设标签宽W,长H
def fast_hist(a, b, n):#--------------------------------------------------------------------------------##   a是转化成一维数组的标签,形状(H×W,);b是转化成一维数组的预测结果,形状(H×W,)#--------------------------------------------------------------------------------#k = (a >= 0) & (a < n)#--------------------------------------------------------------------------------##   np.bincount计算了从0到n**2-1这n**2个数中每个数出现的次数,返回值形状(n, n)#   返回中,写对角线上的为分类正确的像素点#--------------------------------------------------------------------------------#return np.bincount(n * a[k].astype(int) + b[k], minlength=n ** 2).reshape(n, n)  
  • 产生n×n的混淆矩阵统计表
    • 参数a:即:真实的标签gt, 需要reshape为一行输入
    • 参数b:即预测的标签pred,它是经过argmax输出的预测8位标签图, 每个像素表示为类别索引(reshape为一行输入),
    • 参数n:类别数cls_num

  • 首先过滤gt中,类别超过n的索引,确保gt的分类都包含在n个类别中
 k = (a >= 0) & (a < n)
  • 如果要去掉背景,不将背景计算在混淆矩阵,则可以写为:
 k = (a > 0) & (a < n) #去掉了背景,假设0是背景
  • 然后利用np.bincount生成元素个数为n*n的数组,并且reshape n × n n \times n n×n的混淆矩阵,这样确保混淆矩阵行和列都为类别class的个数n
  • n*n数组中,每个元素的值,表示为0~n*n的索引值在x中出现的次数,这样就获得了最终混淆矩阵。这里的x表示为n * a[k] + b[k] , 为啥这么定义呢?

举例如下:将图片的gt标签a和pred输出图片b,都转换为一行; a和b中每个元素代表类别索引

在这里插入图片描述

  • 前面8, 9, 4, 7, 6都预测正确, 对于预测正确的像素来说,n * a + b就是对角线的值; 假设n=10,有10类。n * a + b就是88, 99, 44, 77, 66
  • 紧接着6预测成了5, 因此n * a + b就是65
  • 88, 99, 44, 77, 66就是对角线上的值(如下图红框,65就是预测错误,并且能真实反映把6预测成了5(如下图蓝框
    在这里插入图片描述

3. 语义分割指标计算

在这里插入图片描述

图 混淆矩阵

3.1 IOU计算

方式1(推荐)

计算每个类别的IOU计算:
I O U = T P F N + F P + T P IOU =\frac{TP}{FN+FP+TP} IOU=FN+FP+TPTP

def per_class_iu(hist):return np.diag(hist) / np.maximum((hist.sum(1) + hist.sum(0) - np.diag(hist)), 1) 
  • 输入hist 表示 2维的混淆矩阵,大小为n*n (n为类别数)
  • 混淆矩阵对角线元素值,表示每个类别预测正确的数TP:
np.diag(hist)
  • 其中:混淆矩阵所对应中,每一行为对应类别(如类1)的统计值中,对角线位置为正常预测为该类别的统计值(TP),其他位置则是错误的将该类别预测为其他的类别FN: 因此每个类别的FP统计值为:
FN =hist.sum(1) -TP = hist.sum(1) - np.diag(hist)
  • 同理,预测为该类别所对应的列中,对角线为正确预测,其他位置则是将其他类别错误的预测为该列所对应的类别,也就是FP
FP =hist.sum(0) -TP = hist.sum(0) - np.diag(hist)

因此分母FN_FP+TP=np.maximum(hist.sum(1) + hist.sum(0) - np.diag(hist),1), 这里加上np.maximum确保了分母不为0

方式2
def IOU(pred,target,n_classes = args.num_class ):ious = []# ignore IOU for background classfor cls in range(1,n_classes):pred_inds = pred == clstarget_inds = target == cls# target_sum = target_inds.sum()intersection = (pred_inds[target_inds]).sum()union = pred_inds.sum() + target_inds.sum() - intersectionif union == 0:ious.append(float('nan')) # If there is no ground truth,do not include in evaluationelse:ious.append(float(intersection)/float(max(union,1)))return ious

参考:https://github.com/dilligencer-zrj/code_zoo/blob/master/compute_mIOU

3.2 Precision 计算

每个类别的Precision 计算如下:

P r e c i s i o n = T P T P + F P Precision= \frac{TP}{TP+FP} Precision=TP+FPTP

def per_class_Precision(hist):return np.diag(hist) / np.maximum(hist.sum(0), 1) 
  • 其中 np.diag(hist) 为TP值,hist.sum(0)表示为 TP+FP, np.maximum确保确保分母不为0

3.3 总体的Accuracy计算

总体的Accuracy计算如下:

A c c u r a c y = T P + T N T P + T N + F P + F N Accuracy = \frac{TP+TN}{TP+TN+FP+FN} Accuracy=TP+TN+FP+FNTP+TN
由于是多类别,没有负样本,因此TN为0。

def per_Accuracy(hist):return np.sum(np.diag(hist)) / np.maximum(np.sum(hist), 1) 

3.4 Recall 计算

recall指的是预测为Positive的样本,占所有Positive样本的比率
P r e c i s i o n = T P P Precision= \frac{TP}{P} Precision=PTP

def per_class_PA_Recall(hist):return np.diag(hist) / np.maximum(hist.sum(1), 1) 
  • 每一行统计值为该类别样本的真实数量P, 因此P = hist.sum(1)

3.5 MIOU计算

def compute_mIoU(gt_dir, pred_dir, png_name_list, num_classes, name_classes=None):  print('Num classes', num_classes)  #-----------------------------------------##   创建一个全是0的矩阵,是一个混淆矩阵#-----------------------------------------#hist = np.zeros((num_classes, num_classes))#------------------------------------------------##   获得验证集标签路径列表,方便直接读取#   获得验证集图像分割结果路径列表,方便直接读取#------------------------------------------------#gt_imgs     = [join(gt_dir, x + ".png") for x in png_name_list]  pred_imgs   = [join(pred_dir, x + ".png") for x in png_name_list]  #------------------------------------------------##   读取每一个(图片-标签)对#------------------------------------------------#for ind in range(len(gt_imgs)): #------------------------------------------------##   读取一张图像分割结果,转化成numpy数组#------------------------------------------------#pred = np.array(Image.open(pred_imgs[ind]))  #------------------------------------------------##   读取一张对应的标签,转化成numpy数组#------------------------------------------------#label = np.array(Image.open(gt_imgs[ind]))  # 如果图像分割结果与标签的大小不一样,这张图片就不计算if len(label.flatten()) != len(pred.flatten()):  print('Skipping: len(gt) = {:d}, len(pred) = {:d}, {:s}, {:s}'.format(len(label.flatten()), len(pred.flatten()), gt_imgs[ind],pred_imgs[ind]))continue#------------------------------------------------##   对一张图片计算21×21的hist矩阵,并累加#------------------------------------------------#hist += fast_hist(label.flatten(), pred.flatten(), num_classes)  # 每计算10张就输出一下目前已计算的图片中所有类别平均的mIoU值if name_classes is not None and ind > 0 and ind % 10 == 0: print('{:d} / {:d}: mIou-{:0.2f}%; mPA-{:0.2f}%; Accuracy-{:0.2f}%'.format(ind, len(gt_imgs),100 * np.nanmean(per_class_iu(hist)),100 * np.nanmean(per_class_PA_Recall(hist)),100 * per_Accuracy(hist)))#------------------------------------------------##   计算所有验证集图片的逐类别mIoU值#------------------------------------------------#IoUs        = per_class_iu(hist)PA_Recall   = per_class_PA_Recall(hist)Precision   = per_class_Precision(hist)#------------------------------------------------##   逐类别输出一下mIoU值#------------------------------------------------#if name_classes is not None:for ind_class in range(num_classes):print('===>' + name_classes[ind_class] + ':\tIou-' + str(round(IoUs[ind_class] * 100, 2)) \+ '; Recall (equal to the PA)-' + str(round(PA_Recall[ind_class] * 100, 2))+ '; Precision-' + str(round(Precision[ind_class] * 100, 2)))#-----------------------------------------------------------------##   在所有验证集图像上求所有类别平均的mIoU值,计算时忽略NaN值#-----------------------------------------------------------------#print('===> mIoU: ' + str(round(np.nanmean(IoUs) * 100, 2)) + '; mPA: ' + str(round(np.nanmean(PA_Recall) * 100, 2)) + '; Accuracy: ' + str(round(per_Accuracy(hist) * 100, 2)))  return np.array(hist, np.int), IoUs, PA_Recall, Precision
  • 首先创建一个维度为(num_classes, num_classes)的空混淆矩阵hist
  • 遍历pred_imgsgt_imgs, 将遍历得到的每一张predlabel展平(flatten)到一维,输入到fast_hist计算单张图片预测的混淆矩阵,将每次的计算结果加到总的混淆矩阵hist
for ind in range(len(gt_imgs)): #------------------------------------------------##   读取一张图像分割结果,转化成numpy数组#------------------------------------------------#pred = np.array(Image.open(pred_imgs[ind]))  #------------------------------------------------##   读取一张对应的标签,转化成numpy数组#------------------------------------------------#label = np.array(Image.open(gt_imgs[ind]))  # 如果图像分割结果与标签的大小不一样,这张图片就不计算if len(label.flatten()) != len(pred.flatten()):  print('Skipping: len(gt) = {:d}, len(pred) = {:d}, {:s}, {:s}'.format(len(label.flatten()), len(pred.flatten()), gt_imgs[ind],pred_imgs[ind]))continue#------------------------------------------------##   对一张图片计算21×21的hist矩阵,并累加#------------------------------------------------#hist += fast_hist(label.flatten(), pred.flatten(), num_classes) 
  • 计算10张就输出一下目前已计算的图片中所有类别平均的mIoU
# 每计算10张就输出一下目前已计算的图片中所有类别平均的mIoU值if name_classes is not None and ind > 0 and ind % 10 == 0: print('{:d} / {:d}: mIou-{:0.2f}%; mPA-{:0.2f}%; Accuracy-{:0.2f}%'.format(ind, len(gt_imgs),100 * np.nanmean(per_class_iu(hist)),100 * np.nanmean(per_class_PA_Recall(hist)),100 * per_Accuracy(hist)))
  • 遍历完成后,得到所有类别的Iou值IoUs以及PA_Recall Precision ,并逐类别输出一下mIoU值
   if name_classes is not None:for ind_class in range(num_classes):print('===>' + name_classes[ind_class] + ':\tIou-' + str(round(IoUs[ind_class] * 100, 2)) \+ '; Recall (equal to the PA)-' + str(round(PA_Recall[ind_class] * 100, 2))+ '; Precision-' + str(round(Precision[ind_class] * 100, 2)))
  • 最后在所有验证集图像上求所有类别平均的mIoU值
 print('===> mIoU: ' + str(round(np.nanmean(IoUs) * 100, 2)) + '; mPA: ' + str(round(np.nanmean(PA_Recall) * 100, 2)) + '; Accuracy: ' + str(round(per_Accuracy(hist) * 100, 2)))  

参考

  • https://github.com/bubbliiiing/deeplabv3-plus-pytorch/blob/main/utils/utils_metrics.py
  • https://github.com/dilligencer-zrj/code_zoo/blob/master/compute_mIOU
  • https://www.jianshu.com/p/42939bf83b8a

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

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

相关文章

Docker五部曲之三:镜像构建

文章目录 前言Docker构建架构构建指令构建上下文本地目录Git存储库压缩文件纯文本文件.dockerignore文件 Dockerfile解析器指令环境变量命令执行格式exec格式shell格式 FROMRUNCMDLABELEXPOSEENVADDCOPYENTRYPOINTVOLUMEUSERWORKDIRARGONBUILDSHELL 多级构建 前言 本文均翻译自…

对快速排序思想的进一步理解,分而治之,欧几里得算法(常用求最大公约数的方法)

自己找到的最优的快排的代码 快速排序 思想 分而治之使用欧几里得算法&#xff08;辗转相除法&#xff09;来求解一个应用题 假设有一块地&#xff0c;现在用这个同样大小的正方形来铺满&#xff0c;求所可用的最大的正方形地砖的面积 这两个方法放在一起是因为这个欧几里得要…

Linux环境之Ubuntu安装Docker流程

今天分享Linux环境之Ubuntu安装docker流程&#xff0c;Docker 是目前非常流行的容器&#xff0c;对其基本掌握很有必要。下面我们通过阿里云镜像的方式安装&#xff1a; 本来今天准备用清华大学镜像安装呢&#xff0c;好像有点问题&#xff0c;于是改成阿里云安装了。清华安装…

抓交通肇事犯(python)

问题描述&#xff1a; 一辆卡车违反交通规则&#xff0c;撞人后逃跑。现场有三人目击该事件&#xff0c;但都没有记住车号&#xff0c;只记下了车号的一些特征。甲说&#xff1a;牌照的前两位数字是相同的&#xff1b;乙说&#xff1a;牌照的后两位数字是相同的&#xff0c;但…

GVM垃圾收集器

Serial收集器&#xff08;新生代&#xff09; Serial&#xff08;串行&#xff09;收集器是最基本、历史最悠久的垃圾收集器&#xff0c;采用“标记-复制”算法负责新生代的垃圾收集。它是Hotspot虚拟机运行在客户端模式下的默认新生代收集器。 它是一个单线程收集器。它会使用…

软件测试学到这个程度,面试轻松拿下20K

很多人认为&#xff0c;软件测试是一个简单的职位&#xff0c;职业生涯走向也不会太好&#xff0c;但是随着时间的推移&#xff0c;软件测试行业的变化&#xff0c;人们开始对软件测试行业的认知有了新的高度&#xff0c;越来越多的人开始关注这个行业&#xff0c;开始重视这个…

v-if控制div内容显示,克隆这个div但是v-if没有效果

问题描述&#xff1a; 我的子页面打印的时候通过isPdf来隐藏“选择参加人员”按钮。 我子页面有个el-dialog&#xff0c;el-dialog里面有个大的div它的id为app-pre-meet-add&#xff0c;在子页面我通过isPdf来显示我想要的内容。现在我在父页面先通过this.$refs.child.control…

分布式缓存

分布式缓存 缓存雪崩 缓存雪崩我们可以简单的理解为&#xff1a;由于原有缓存失效&#xff0c;新缓存未到期间所有原本应该访问缓存的请求都去查询数据库了&#xff0c;而对数据库 CPU 和内存造成巨大压力&#xff0c;严重的会造成数据库宕机。从而形成一系列连锁反应&#xf…

C++与Typescript的区别

目录 一、C类模板和函数模板 1.类模板 2.函数模板 二&#xff0c;Typescript 的泛型声明 1.泛型函数 2.泛型类 为什么C和Typescript语言中主张模板和泛型 一、C类模板和函数模板 在C中&#xff0c;类模板和函数模板允许你为多种数据类型编写通用的代码。这就像每个人都有…

山西电力市场日前价格预测【2024-01-14】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2024-01-14&#xff09;山西电力市场全天平均日前电价为415.13元/MWh。其中&#xff0c;最高日前电价为851.84元/MWh&#xff0c;预计出现在18:15。最低日前电价为198.87元/MWh&#xff0c;预计…

使用 C++/WinRT 创作 API

如果 API 位于 Windows 命名空间中 这是你使用 Windows 运行时 API 最常见的情况。 对于元数据中定义的 Windows 命名空间中的每个类型&#xff0c;C/WinRT 都定义了 C 友好等效项&#xff08;称为投影类型 &#xff09;。 投影类型具有与 Windows 类型相同的完全限定名称&…

【LabVIEW FPGA入门】使用CompactRIO进行SPI和I2C通信

NI提供了 SPI and I2C Driver API&#xff1a;下载SPI and I2C Driver API - NI 该API使用FPGA数字I / O线与SPI或I2C设备进行通信。 选择数字硬件时&#xff0c;要考虑三个选项&#xff1a; NI Single-Board RIO硬件可同时使用SPI和I2C驱动程序。NI 9401 C系列模块与SPI驱动程…

大型语言模型,用最少的数学和行话进行解释

本文来自于《Large language models, explained with a minimum of math and jargon》&#xff0c;不嵌入任何笔者的个人理解&#xff0c;只是对原文的总结与记录。 文章作者是Tim Lee和Sean Trott&#xff0c;Tim Lee是一位拥有计算机科学硕士学位的记者&#xff0c;Sean Trot…

【二十】【动态规划】879. 盈利计划、377. 组合总和 Ⅳ、96. 不同的二叉搜索树 ,三道题目深度解析

动态规划 动态规划就像是解决问题的一种策略&#xff0c;它可以帮助我们更高效地找到问题的解决方案。这个策略的核心思想就是将问题分解为一系列的小问题&#xff0c;并将每个小问题的解保存起来。这样&#xff0c;当我们需要解决原始问题的时候&#xff0c;我们就可以直接利…

关于jupyter突然打不开的问题

好久没有用python了&#xff0c;我的电脑环境是安装过anaconda和pycharm&#xff0c;但是有些简单的东西就希望在jupyter中测试一下&#xff0c;但是最近发现jupyter打不开了。 具体是&#xff1a; 在这里打开jupyter是可以的&#xff0c;但是在命令行就不行&#xff0c;表现为…

计算机毕业设计 | SpringBoot+vue的家庭理财 财务管理系统(附源码)

1&#xff0c;绪论 1.1 项目背景 网络的发展已经过去了七十多年&#xff0c;网络技术的发展&#xff0c;将会影响到人类的方方面面&#xff0c;网络的出现让各行各业都得到了极大的发展&#xff0c;为整个社会带来了巨大的生机。 现在许多的产业都与因特网息息相关&#xff…

Python实现华容道问题详解

概要 华容道是一种古老的中国益智游戏&#xff0c;最早出现在中国的《千古文馆》中。这个游戏的目标是将一块特殊的方块从一个方形的棋盘中移出&#xff0c;通过滑动其他的方块来达到这个目标。本文将介绍如何使用Python来实现华容道问题&#xff0c;并提供详细的代码示例。 游…

飞鱼CRM接入第三方系统 飞鱼API对接详细教程

场景描述 在白码低代码开发平台中&#xff0c;是支持外部crm系统的线索通过接口流入到白码系统里面&#xff0c;换而言之&#xff0c;只要外部的系统有线索api接口&#xff0c;白码系统可以接收线索并在白码系统上进行后续操作。本文以飞鱼crm系统为例&#xff0c;讲解如何接收…

学习就要从简单的开始嘛,开始学一个个人博客吧

做一个个人博客第一步该怎么做&#xff1f; 好多零基础的同学们不知道怎么迈出第一步。 那么&#xff0c;就找一个现成的模板学一学呗&#xff0c;毕竟我们是高贵的Ctrl c v 工程师。 但是这样也有个问题&#xff0c;那就是&#xff0c;那些模板都&#xff0c;太&#xff01;…

Linux/Haystack

Enumeration nmap 还是先看看端口对外开放情况&#xff0c;对外开放了22,80,9200 22应该是ssh&#xff0c;80是web&#xff0c;9200不知道是什么 TCP/80 访问web&#xff0c;没有什么链接&#xff0c;只有一张图片 有可能图片中有些东西&#xff0c;但还是尝试扫描一下网站…