蚊子雷达追踪打击系统-源码

查看 75|回复 10
作者:killerzeno   
蚊子雷达追踪打击系统-源码
[color=]奇葩软件千千万,我的工具占一半
[color=]打包及程序介绍见原创发布区


微信截图_20250520155301.jpg (307.67 KB, 下载次数: )
下载附件
2025-5-20 16:22 上传

[Python] 纯文本查看 复制代码import cv2
import numpy as np
import matplotlib
import math
from matplotlib import pyplot as plt
from matplotlib import rcParams
from matplotlib.animation import FuncAnimation
from collections import deque
from datetime import datetime
import time
import pygame
import os
import wave
import struct
# **添加以下两行设置后端**
matplotlib.use('Qt5Agg')  # 替换原有的'TkAgg'
# 在独立线程中运行Matplotlib动画
import threading
# 设置中文字体
rcParams['font.family'] = 'SimHei'
rcParams['axes.unicode_minus'] = False
# 生成驱蚊音频文件
def generate_anti_mosquito_sound():
    sample_rate = 44100  # 采样率:每秒采集44100个音频样本
    duration = 3.0  # 音频时长:3秒
    freq = 22000  # 频率:22000Hz(超声波,接近蚊子能感知的上限)
    samples = []
    for i in range(int(duration * sample_rate)):
        sample = 0.5 * math.sin(2 * math.pi * freq * i / sample_rate)
        samples.append(sample)
    filename = "mosquito_sound.wav"
    with wave.open(filename, 'w') as wf:
        wf.setnchannels(1)
        wf.setsampwidth(2)
        wf.setframerate(sample_rate)
        for sample in samples:
            data = struct.pack(' 0:
            speed = np.sqrt(dx ** 2 + dy ** 2) / dt
            direction = np.degrees(np.arctan2(dy, dx))
            self.speeds.append(speed)
            self.directions.append(direction)
        self.positions.append((x, y, time))
        self.last_update = time
        self.active = True
    def get_current_speed(self):
        return np.mean(self.speeds[-3:]) if len(self.speeds) > 0 else 0
    def get_current_direction(self):
        if len(self.directions) > 0:
            return self.directions[-1]
        return None
tracks = []
next_id = 1
def play_anti_mosquito_sound():
    if system_state.auto_sound and mosquito_sound:
        current_time = time.time()
        if current_time - system_state.last_sound_time > 5:
            try:
                mosquito_sound.play()
                system_state.last_sound_time = current_time
                system_state.sound_playing = True
            except Exception as e:
                print(f"播放音频失败: {e}")
def take_screenshot():
    screenshot_dir = "screenshots"
    if not os.path.exists(screenshot_dir):
        os.makedirs(screenshot_dir)
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    filename = f"{screenshot_dir}/screenshot_{system_state.screenshot_count}_{timestamp}.png"
    plt.savefig(filename)
    system_state.screenshot_count += 1
    print(f"截图已保存: {filename}")
def update_radar(frame):
    global current_angle, r, mosquito_count, max_mosquito_count
    global false_positives, true_positives, tracks, next_id
    global scan_arc, scan_arc_fill, trail_lines
    current_time = time.time()
    # 转换为灰度图像
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # 应用背景减法检测运动
    fgmask = fgbg.apply(gray)
    # 形态学操作
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
    fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
    fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_CLOSE, kernel)
    # 寻找轮廓
    contours, _ = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    # 检测到的蚊子位置
    current_detections = []
    mosquito_info = []
    for contour in contours:
        area = cv2.contourArea(contour)
        perimeter = cv2.arcLength(contour, True)
        if 5  10:
            (x, y), radius = cv2.minEnclosingCircle(contour)
            if 2  0 else 0
                if circularity > 0.5:
                    center_x = x - frame.shape[1] // 2
                    center_y = y - frame.shape[0] // 2
                    angle = np.arctan2(center_y, center_x) % (2 * np.pi)
                    distance = np.sqrt(center_x ** 2 + center_y ** 2)
                    distance = min(distance, max_distance)
                    current_detections.append((x, y, angle, distance, area, radius))
    # 多目标跟踪
    active_tracks = [t for t in tracks if t.active]
    matched = [False] * len(current_detections)
    for track in active_tracks:
        min_dist = float('inf')
        best_match = None
        for i, (x, y, _, _, _, _) in enumerate(current_detections):
            if not matched:
                last_x, last_y, _ = track.positions[-1]
                dist = np.sqrt((x - last_x) ** 2 + (y - last_y) ** 2)
                if dist  0.5:
            track.active = False
    # 更新雷达数据
    mosquito_count = len([t for t in tracks if t.active])
    max_mosquito_count = max(max_mosquito_count, mosquito_count)
    # 播放驱蚊声
    if mosquito_count > 0:
        play_anti_mosquito_sound()
    # 更新扫描线效果
    current_angle = (current_angle + scan_speed * 2) % 360  # 加快扫描速度
    scan_rad = np.radians(current_angle)
    # 主扫描线
    scan_line.set_data([scan_rad, scan_rad], [0, max_distance])
    # 扫描线尾迹
    trail_length = 30
    trail_angles = np.linspace(scan_rad - np.radians(trail_length), scan_rad, 10)
    scan_shadow.set_data(trail_angles, [max_distance] * 10)
    # 更新扇形扫描区域
    if scan_arc is not None:
        scan_arc.remove()
    if scan_arc_fill is not None:
        scan_arc_fill.remove()
    scan_width = 30
    scan_start = np.radians(current_angle - scan_width) % (2 * np.pi)
    scan_end = np.radians(current_angle + scan_width) % (2 * np.pi)
    # 扇形边框
    scan_theta = np.linspace(scan_start, scan_end, 50)
    scan_arc = ax_radar.plot(scan_theta, [max_distance] * 50,
                             color='lime', alpha=0.5, linewidth=1)[0]
    # 扇形填充(渐变效果)
    scan_r = np.linspace(0, max_distance, 50)
    scan_theta, scan_r = np.meshgrid(scan_theta, scan_r)
    scan_theta = scan_theta.flatten()
    scan_r = scan_r.flatten()
    angle_diff = np.abs((np.degrees(scan_theta) - current_angle + 180) % 360 - 180)
    alphas = np.where(angle_diff  1:
                # 主轨迹线
                history_angles = []
                history_distances = []
                for i in range(max(0, len(track.positions) - 5), len(track.positions)):
                    x, y, _ = track.positions
                    center_x = x - frame.shape[1] // 2
                    center_y = y - frame.shape[0] // 2
                    angle = np.arctan2(center_y, center_x) % (2 * np.pi)
                    distance = np.sqrt(center_x ** 2 + center_y ** 2)
                    history_angles.append(angle)
                    history_distances.append(distance)
                if len(history_angles) > 1:
                    # 主轨迹线
                    main_line = ax_radar.plot(history_angles, history_distances,
                                              color='cyan', alpha=0.7,
                                              linewidth=1.5, zorder=5)[0]
                    trail_lines.append(main_line)
                    # 轨迹尾迹
                    trail_alpha = 0.3
                    for i in range(1, 4):
                        if len(history_angles) > i:
                            trail_line = ax_radar.plot(
                                history_angles[-i - 1:-i],
                                history_distances[-i - 1:-i],
                                color='white', alpha=trail_alpha,
                                linewidth=2 + i, zorder=4 - i)[0]
                            trail_lines.append(trail_line)
                            trail_alpha *= 0.7
    # 更新信息面板
    accuracy = true_positives / (true_positives + false_positives) * 100 if (
                                                                                    true_positives + false_positives) > 0 else 0
    info_texts[0].set_text(f"状态: 运行中")
    info_texts[1].set_text(f"扫描中")
    info_texts[2].set_text(f"摄像头: 开启")
    info_texts[3].set_text(f"启动: {system_state.start_time.strftime('%H:%M:%S')}")
    info_texts[4].set_text(f"当前: {mosquito_count}")
    info_texts[5].set_text(f"今日: {system_state.detected_today}")
    info_texts[6].set_text(f"最大: {max_mosquito_count}")
    info_texts[7].set_text(
        f"平均: {system_state.total_detected / ((time.time() - system_state.start_time.timestamp()) / 3600):.1f}/h")
    if mosquito_info:
        _, _, track = mosquito_info[0]
        speed = track.get_current_speed()
        direction = track.get_current_direction()
        dir_text = f"{direction:.1f}°" if direction is not None else "-"
        info_texts[8].set_text(f"速度: {speed:.1f} px/s")
        info_texts[9].set_text(f"大小: {track.positions[-1][2]:.1f} px")
        info_texts[10].set_text(f"方向: {dir_text}")
        info_texts[11].set_text(f"距离: {distance:.1f} cm")
    else:
        info_texts[8].set_text(f"速度: 0 px/s")
        info_texts[9].set_text(f"大小: 0 px")
        info_texts[10].set_text(f"方向: -")
        info_texts[11].set_text(f"距离: 0 cm")
    info_texts[12].set_text(f"追踪: {len(tracks)}")
    info_texts[13].set_text(f"历史: {system_state.total_detected}")
    info_texts[14].set_text(f"误报: {false_positives}")
    info_texts[15].set_text(f"准确率: {accuracy:.1f}%")
    sound_status = "开启" if system_state.auto_sound else "关闭"
    playing_status = "(播放中)" if system_state.sound_playing else ""
    info_texts[16].set_text(f"声波驱蚊: {sound_status} {playing_status}")
    info_texts[17].set_text(f"按A键切换")
    info_texts[18].set_text(f"截图: 按P键")
    return [scan_line, scan_shadow, mosquito_dots, scan_arc, scan_arc_fill,
            *trail_lines, *info_texts]
# 创建动画
def update(frame):
    ret, frame = cap.read()
    if not ret:
        return []
    frame = cv2.flip(frame, 1)
    # 灰度处理与边缘检测
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray_frame, (5, 5), 0)
    edges = cv2.Canny(blurred, EDGE_THRESHOLD1, EDGE_THRESHOLD2)
    # 寻找轮廓
    contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    # 创建空白图像用于绘制轮廓
    edge_display = np.zeros_like(frame)
    cv2.drawContours(edge_display, contours, -1, (0, 255, 0), 1)
    artists = update_radar(frame)
    # 显示窗口
    cv2.imshow('Mosquito Tracking', cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
    cv2.imshow('Edges', edge_display)  # 显示轮廓绘制结果
    key = cv2.waitKey(1)
    if key & 0xFF == ord('q'):
        ani.event_source.stop()
        cap.release()
        cv2.destroyAllWindows()
        plt.close('all')
        return []
    elif key & 0xFF == ord('a'):
        system_state.auto_sound = not system_state.auto_sound
    elif key & 0xFF == ord('p'):
        take_screenshot()
    if system_state.sound_playing and not pygame.mixer.get_busy():
        system_state.sound_playing = False
    return artists
# 开始动画
try:
    # 启动时自动播放一次声波
    if system_state.auto_sound and mosquito_sound:
        mosquito_sound.play()
        system_state.sound_playing = True
        system_state.last_sound_time = time.time()
    ani = FuncAnimation(fig, update, frames=None, interval=30, blit=True, cache_frame_data=False)
    plt.tight_layout()
    plt.show()
except Exception as e:
    print(f"程序错误: {e}")
finally:
    if 'cap' in locals() and cap.isOpened():
        cap.release()
    cv2.destroyAllWindows()
    plt.close('all')

蚊子, 初始化

wish2086   

太强了,还缺个红外远程击杀大炮
ycycn   

图像识别 还是  雷达波 ?
cbweixin   

牛。 很有启发
iefydi   

这个就像六脉神剑一样,牛
发飙的熊猫君   

有没有硬件的bom,可以复刻一个玩玩
bp13   


wish2086 发表于 2025-5-20 16:30
太强了,还缺个红外远程击杀大炮

激光大炮
三字经123   

可以指挥激光笔打蚊子?
weiyuhero   

人才 绝对人才
天业电子   

这也可以  很6
您需要登录后才可以回帖 登录 | 立即注册