动态绘制入侵检测区域矩形

import cv2 as cv
import numpy as np
import pygetwindow as gw
import mss
import torch

# 定义窗口标题
window_title = "Plants vs. Zombies"

# 定义置信度阈值
CONFIDENCE_THRESHOLD = 0.5

# 加载YOLOv5模型
model = torch.hub.load('..', 'custom', path='../runs/train/exp48/weights/best.pt', source='local')

# 全局变量,用于处理鼠标事件
start_point = None
end_point = None
drawing = False
monitoring_area = []

def get_window_rect(title):
    """
    获取指定标题窗口的矩形区域。
    """
    windows = gw.getWindowsWithTitle(title)
    if not windows:
        raise ValueError(f"Window with title '{title}' not found.")
    return windows[0]._rect

def capture_screen(rect):
    """
    捕获屏幕上指定矩形区域的图像。
    """
    with mss.mss() as sct:
        monitor = {"left": rect.left, "top": rect.top, "width": rect.width, "height": rect.height}
        img = sct.grab(monitor)
        img_np = np.array(img)
        img_np = cv.cvtColor(img_np, cv.COLOR_BGRA2BGR)  # 将BGRA图像转换为BGR图像
        return img_np

def detect_objects(img):
    """
    使用YOLOv5模型检测图像中的物体。
    """
    img_rgb = cv.cvtColor(img, cv.COLOR_BGR2RGB)  # 将图像从BGR转换为RGB
    results = model(img_rgb)  # 执行推断
    detections = results.pandas().xyxy[0]  # 解析检测结果
    detections = detections[detections['confidence'] >= CONFIDENCE_THRESHOLD]  # 过滤低置信度的检测结果
    return detections

def draw_boxes(img, detections):
    """
    在图像上绘制检测到的物体的边界框和标签。
    """
    for _, row in detections.iterrows():
        x1, y1, x2, y2 = int(row['xmin']), int(row['ymin']), int(row['xmax']), int(row['ymax'])
        conf = row['confidence']
        label = row['name']
        color = (0, 255, 0)  # 绿色,用于绘制边界框

        # 绘制边界框
        cv.rectangle(img, (x1, y1), (x2, y2), color, 2)
        # 绘制标签
        label_text = f"{label} {conf:.2f}"
        label_size, _ = cv.getTextSize(label_text, cv.FONT_HERSHEY_SIMPLEX, 0.5, 2)
        label_x1 = x1
        label_y1 = y1 - 10 if y1 - 10 > 10 else y1 + 10
        cv.rectangle(img, (label_x1, label_y1 - label_size[1]), (label_x1 + label_size[0], label_y1 + 2), color, -1)
        cv.putText(img, label_text, (label_x1, label_y1), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1)
    return img

def mouse_callback(event, x, y, flags, param):
    """
    处理鼠标事件,用于绘制矩形区域。
    """
    global start_point, end_point, drawing, monitoring_area

    if event == cv.EVENT_LBUTTONDOWN:
        # 鼠标左键按下时,记录起始点
        start_point = (x, y)
        drawing = True

    elif event == cv.EVENT_MOUSEMOVE:
        if drawing:
            # 鼠标移动时,更新矩形区域的终点
            end_point = (x, y)
            monitoring_area = [start_point, (end_point[0], start_point[1]),
                               end_point, (start_point[0], end_point[1])]

    elif event == cv.EVENT_LBUTTONUP:
        # 鼠标左键松开时,更新矩形区域
        end_point = (x, y)
        drawing = False
        monitoring_area = [start_point, (end_point[0], start_point[1]),
                           end_point, (start_point[0], end_point[1])]

def draw_rectangle(img, rect_points):
    """
    在图像上绘制矩形区域。
    """
    if rect_points:
        rect_points = np.array(rect_points, np.int32)
        rect_points = rect_points.reshape((-1, 1, 2))
        cv.polylines(img, [rect_points], isClosed=True, color=(255, 0, 0), thickness=2)  # 红色,用于绘制矩形区域
    return img

def main():
    """
    主函数,执行屏幕捕获、物体检测和显示操作。
    """
    global monitoring_area

    try:
        rect = get_window_rect(window_title)
        print("Monitoring Window Rect:", rect)

        # 创建窗口并设置鼠标回调
        cv.namedWindow("Plants vs. Zombies")
        cv.setMouseCallback("Plants vs. Zombies", mouse_callback)

        while True:
            img = capture_screen(rect)  # 捕获屏幕图像
            detections = detect_objects(img)  # 检测图像中的物体
            img = draw_boxes(img, detections)  # 绘制检测到的物体的边界框和标签
            # Print detections to console
            if not detections.empty:
                print("Detected objects:")
                for _, row in detections.iterrows():
                    print(f"Label: {row['name']}, Confidence: {row['confidence']:.2f}, "
                          f"Bounding Box: ({row['xmin']}, {row['ymin']}) to ({row['xmax']}, {row['ymax']})")
            # 绘制矩形区域
            img = draw_rectangle(img, monitoring_area)

            # 计算并显示入侵个数
            intrusion_count = 0
            for _, row in detections.iterrows():
                x1, y1, x2, y2 = int(row['xmin']), int(row['ymin']), int(row['xmax']), int(row['ymax'])
                if (start_point and end_point and
                    min(start_point[0], end_point[0]) < x1 < max(start_point[0], end_point[0]) and
                    min(start_point[1], end_point[1]) < y1 < max(start_point[1], end_point[1]) and
                    min(start_point[0], end_point[0]) < x2 < max(start_point[0], end_point[0]) and
                    min(start_point[1], end_point[1]) < y2 < max(start_point[1], end_point[1])):
                    intrusion_count += 1

            # 显示入侵个数
            cv.putText(img, f"Intrusion Count: {intrusion_count}", (50, 50), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

            # 显示图像
            cv.imshow("Plants vs. Zombies", img)

            # 按 'q' 键退出循环
            if cv.waitKey(1) == ord('q'):
                break

    except Exception as e:
        print(f"Error: {e}")

    cv.destroyAllWindows()

if __name__ == "__main__":
    main()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenLayers是一个开源的JavaScript库,用于创建交互式的Web地图。在OpenLayers中,动态绘制矩形可以通过事件监听和坐标处理来实现。下面是简单的步骤: 1. 引入OpenLayers库和相关的模块: ```html <script src="https://openlayers.org/en/v6.6.3/build/ol.js"></script> ``` 2. 创建一个`Map`对象,并添加一个`View`: ```javascript var map = new ol.Map({ target: 'map', // 在HTML中指定容器id view: new ol.View({ center: [0, 0], // 地图中心点 zoom: 2 // 初始缩放级别 }) }); ``` 3. 添加图层(如WMS、Tiles或GeoJSON): ```javascript var layer = new ol.layer.Tile({source: new ol.source.OSM()}); map.addLayer(layer); ``` 4. 使用鼠标事件监听器来绘制矩形: ```javascript map.on('pointerdown', function(e) { var rectangle = new ol.geom.Rectangle([e.coordinate]); // 基于点击坐标创建初始矩形 var drawnFeature = new ol.Feature(rectangle); var vectorSource = new ol.source.Vector({features: [drawnFeature]}); var vectorLayer = new ol.layer.Vector({source: vectorSource}); map.addLayer(vectorLayer); map.forEachFeatureAtPixel(e.pixel, function(feature) { if (feature instanceof ol.Feature) { feature.setGeometry(null); // 清除原有矩形 drawnFeature.setGeometry(rectangle.extend(feature.getGeometry().getExtent())); // 更新矩形大小到包括鼠标下的所有特征 } }); }); // 当鼠标抬起时,清除矩形 map.on('pointerup', function() { map.forEachFeatureAtPixel(map.getEventPixel(e), function(feature) { if (feature instanceof ol.Feature) { feature.setGeometry(null); } }); }); ``` 这里我们监听了`pointerdown`事件开始绘制矩形,`pointerup`事件结束绘制并清除矩形。注意这只是一个基本示例,实际应用可能还需要处理移动、拖拽等更复杂的交互。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值