107 lines
4.4 KiB
Python
107 lines
4.4 KiB
Python
#静态检测,图片检测
|
||
|
||
from ultralytics import YOLO # ultralytics是yolo模型的实现库
|
||
import cv2 # cv2是opencv库,用于图像处理
|
||
import os # os用于文件和目录操作
|
||
|
||
# 替换为实际的模型路径
|
||
model_path = r'\detect\train\weights\best.pt' # 加载yolo模型
|
||
model = YOLO(model_path) # model是加载后的yolo模型实例
|
||
|
||
def infer_and_draw(image_path, output_folder):
|
||
# 检查 image_path 是否是文件夹路径
|
||
if os.path.isdir(image_path):
|
||
# 遍历文件夹中的所有图像文件
|
||
for filename in os.listdir(image_path):
|
||
file_path = os.path.join(image_path, filename)
|
||
if file_path.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')):
|
||
process_image(file_path, output_folder)
|
||
else:
|
||
# 处理单张图像
|
||
process_image(image_path, output_folder)
|
||
|
||
def process_image(image_path, output_folder):
|
||
# 使用模型进行推理
|
||
results = model(image_path)
|
||
original_img = cv2.imread(image_path) # 读取原始图像
|
||
|
||
if results:
|
||
for result in results:
|
||
if result.boxes is not None and len(result.boxes.xyxy) > 0:
|
||
boxes = result.boxes.xyxy.cpu().numpy() # 获取检测框
|
||
classes = result.boxes.cls.cpu().numpy() # 获取类别
|
||
confidences = result.boxes.conf.cpu().numpy() # 获取置信度
|
||
|
||
# 确保输出文件夹存在
|
||
if not os.path.exists(output_folder):
|
||
os.makedirs(output_folder)
|
||
|
||
# 存储所有检测框的标签和位置
|
||
detected_boxes = []
|
||
|
||
for i, box in enumerate(boxes):
|
||
x1, y1, x2, y2 = map(int, box[:4])
|
||
class_id = int(classes[i]) if len(classes) > i else 0
|
||
# 标签映射(假设0表示人头类别)
|
||
label = "head" if class_id == 0 else "unknown"
|
||
conf = confidences[i] if len(confidences) > i else 0.0
|
||
|
||
detected_boxes.append((x1, y1, x2, y2, label, conf))
|
||
|
||
# 避免重叠框的问题,通过过滤和合并框
|
||
filtered_boxes = filter_and_merge_boxes(detected_boxes)
|
||
|
||
# 生成最终的标注图像
|
||
img_annotated = original_img.copy()
|
||
for (x1, y1, x2, y2, label, conf) in filtered_boxes:
|
||
cv2.rectangle(img_annotated, (x1, y1), (x2, y2), (0, 255, 0), 2)
|
||
cv2.putText(img_annotated, f'{label} {conf:.2f}', (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
|
||
|
||
# 保存标注后的图像
|
||
output_image_path = os.path.join(output_folder, os.path.basename(image_path))
|
||
cv2.imwrite(output_image_path, img_annotated)
|
||
print(f"Saved annotated image to: {output_image_path}")
|
||
|
||
# 显示图像(可选)
|
||
cv2.imshow('Detected Image', img_annotated)
|
||
cv2.waitKey(0)
|
||
cv2.destroyAllWindows()
|
||
else:
|
||
print("No detections found.")
|
||
# 保存原始图像
|
||
output_image_path = os.path.join(output_folder, os.path.basename(image_path))
|
||
cv2.imwrite(output_image_path, original_img)
|
||
print(f"Saved original image to: {output_image_path}")
|
||
|
||
def filter_and_merge_boxes(boxes):
|
||
"""
|
||
简单地合并重叠框的逻辑。可以根据需要调整合并算法。
|
||
"""
|
||
filtered_boxes = []
|
||
threshold = 0.5 # 重叠阈值
|
||
|
||
def iou(box1, box2):
|
||
x1, y1, x2, y2 = box1
|
||
x1_, y1_, x2_, y2_ = box2
|
||
ix1, iy1 = max(x1, x1_), max(y1, y1_)
|
||
ix2, iy2 = min(x2, x2_), min(y2, y2_)
|
||
iw = max(ix2 - ix1 + 1, 0)
|
||
ih = max(iy2 - iy1 + 1, 0)
|
||
inter = iw * ih
|
||
ua = (x2 - x1 + 1) * (y2 - y1 + 1) + (x2_ - x1_ + 1) * (y2_ - y1_) - inter
|
||
return inter / ua
|
||
|
||
for i, box1 in enumerate(boxes):
|
||
keep = True
|
||
for j, box2 in enumerate(filtered_boxes):
|
||
if iou(box1[:4], box2[:4]) > threshold:
|
||
keep = False
|
||
break
|
||
if keep:
|
||
filtered_boxes.append(box1)
|
||
|
||
return filtered_boxes
|
||
|
||
# 使用实际图像路径或文件夹路径进行推理,并指定输出文件夹
|
||
infer_and_draw(r'\assets\xx.jpg(图片路径)', r'ultralytics\output(输出路径)')
|