我想要一份结肠息肉图像目标检测的精度和敏感性指标python代码,标签格式为xml
时间: 2024-05-11 13:18:20 浏览: 146
好的,你需要先安装以下库:
- opencv-python
- lxml
然后按照以下步骤进行操作:
1. 将标签文件夹和图片文件夹放在同一目录下,并将标签文件夹命名为"Annotations",图片文件夹命名为"JPEGImages"。
2. 运行以下代码:
```python
import cv2
import os
import numpy as np
import xml.etree.ElementTree as ET
# 检测结果存储路径
result_path = "detection_results"
if not os.path.exists(result_path):
os.makedirs(result_path)
# 标签和图片路径
annotation_path = "Annotations"
image_path = "JPEGImages"
# 目标类别
classes = ["polyp"]
# 读取标签文件
def parse_annotation(annotation_path, image_path):
tree = ET.parse(annotation_path)
root = tree.getroot()
boxes = []
for obj in root.iter("object"):
cls = obj.find("name").text
if cls not in classes:
continue
xmlbox = obj.find("bndbox")
xmin = int(xmlbox.find("xmin").text)
ymin = int(xmlbox.find("ymin").text)
xmax = int(xmlbox.find("xmax").text)
ymax = int(xmlbox.find("ymax").text)
boxes.append([xmin, ymin, xmax, ymax])
if not boxes:
return None, None
else:
img = cv2.imread(os.path.join(image_path, root.find("filename").text))
return img, np.array(boxes)
# 绘制检测框
def draw_box(img, box):
xmin, ymin, xmax, ymax = box.astype(np.int)
cv2.rectangle(img, (xmin, ymin), (xmax, ymax), (0, 255, 0), 2)
# 计算IOU
def iou(box1, box2):
xmin1, ymin1, xmax1, ymax1 = box1
xmin2, ymin2, xmax2, ymax2 = box2
inter_xmin = max(xmin1, xmin2)
inter_ymin = max(ymin1, ymin2)
inter_xmax = min(xmax1, xmax2)
inter_ymax = min(ymax1, ymax2)
inter_area = max(0, inter_xmax - inter_xmin + 1) * max(0, inter_ymax - inter_ymin + 1)
area1 = (xmax1 - xmin1 + 1) * (ymax1 - ymin1 + 1)
area2 = (xmax2 - xmin2 + 1) * (ymax2 - ymin2 + 1)
iou = inter_area / float(area1 + area2 - inter_area)
return iou
# 计算AP
def compute_ap(recall, precision):
recall = np.concatenate(([0.], recall, [1.]))
precision = np.concatenate(([0.], precision, [0.]))
for i in range(precision.size - 2, -1, -1):
precision[i] = max(precision[i], precision[i+1])
idx = np.where(recall[1:] != recall[:-1])[0]
ap = np.sum((recall[idx + 1] - recall[idx]) * precision[idx + 1])
return ap
# 计算mAP
def compute_map(det_results, gt_boxes):
det_results = sorted(det_results, key=lambda x: x[1], reverse=True)
tp = np.zeros(len(det_results))
fp = np.zeros(len(det_results))
for i, det in enumerate(det_results):
box, score = det
ious = [iou(box, gt_box) for gt_box in gt_boxes]
max_iou = np.max(ious)
max_idx = np.argmax(ious)
if max_iou >= 0.5:
if not tp[max_idx]:
tp[i] = 1
else:
fp[i] = 1
else:
fp[i] = 1
tp = np.cumsum(tp)
fp = np.cumsum(fp)
recall = tp / float(len(gt_boxes))
precision = tp / np.maximum(tp + fp, np.finfo(np.float64).eps)
ap = compute_ap(recall, precision)
return ap
# 加载模型
net = cv2.dnn.readNet("model.weights", "model.cfg")
# 获取输出层信息
layer_names = net.getLayerNames()
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
# 遍历图片和标签
detection_results = []
gt_boxes = []
for i, filename in enumerate(os.listdir(annotation_path)):
print("processing %d/%d" % (i+1, len(os.listdir(annotation_path))), end="\r")
annotation_file = os.path.join(annotation_path, filename)
image_file = os.path.join(image_path, os.path.splitext(filename)[0] + ".jpg")
img, boxes = parse_annotation(annotation_file, image_path)
if img is None:
continue
gt_boxes += list(boxes)
# 图像预处理
blob = cv2.dnn.blobFromImage(img, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
# 模型推理
net.setInput(blob)
outs = net.forward(output_layers)
class_ids = []
confidences = []
boxes = []
for out in outs:
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.5 and class_id == 0:
center_x = int(detection[0] * img.shape[1])
center_y = int(detection[1] * img.shape[0])
w = int(detection[2] * img.shape[1])
h = int(detection[3] * img.shape[0])
xmin = int(center_x - w / 2)
ymin = int(center_y - h / 2)
xmax = int(center_x + w / 2)
ymax = int(center_y + h / 2)
boxes.append([xmin, ymin, xmax, ymax])
confidences.append(float(confidence))
class_ids.append(class_id)
# 非极大抑制
indices = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
for i in indices:
i = i[0]
box = boxes[i]
score = confidences[i]
detection_results.append([box, score])
draw_box(img, box)
cv2.putText(img, "%.2f" % score, (box[0], box[1]-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
# 保存检测结果
cv2.imwrite(os.path.join(result_path, os.path.splitext(filename)[0] + ".jpg"), img)
# 计算指标
ap = compute_map(detection_results, gt_boxes)
recall = np.linspace(0, 1, 11)
precision = []
for r in recall:
p = compute_ap(np.array([r]), np.array([1]))
precision.append(p)
precision = np.array(precision)
mAP = np.mean(precision)
# 输出结果
print("mAP: %.4f" % mAP)
print("AP: %.4f" % ap)
```
这段代码会遍历标签文件夹和图片文件夹,进行目标检测,并计算指标。检测结果会保存在"detection_results"文件夹中,指标会在控制台输出。
希望对你有帮助!
阅读全文