D:\EVE_A_Eye-main\EVE_A_Eye>python main.py
Traceback (most recent call last):
File "D:\EVE_A_Eye-main\EVE_A_Eye\main.py", line 19, in <module>
import matplotlib.pyplot as plt
ModuleNotFoundError: No module named 'matplotlib'
import os
import time
import threading
from PIL import Image, ImageFile, UnidentifiedImageError
ImageFile.LOAD_TRUNCATED_IMAGES = True
import cv2
import uiautomation as auto
from uiautomation.uiautomation import Bitmap
import win32clipboard
import win32con
from ctypes import *
import pyautogui
# -*- coding: utf-8 -*-
import os
import sys
import time
import numpy as np
import cv2
import matplotlib.pyplot as plt
from pyhalcon import *
def qo2ul_device_monitoring_solution():
"""
qo2ul设备异常监测完整解决方案
输入:实时采集的工业图像
输出:相似度分析结果与异常定位
"""
try:
# 初始化Halcon环境
dev_open_window(0, 0, 800, 600, 'black', WindowHandle)
set_system('use_window_thread', 'true')
# === 1. 图像采集与预处理 ===
# [引用1: 设备通信框架]
grab_image(Image, AcqHandle) # 从工业相机捕获图像
dev_display(Image)
rgb1_to_gray(Image, GrayImage) # 转灰度图
# === 2. 模板匹配核心算法 ===
# [引用3: Halcon模板匹配技术]
gen_rectangle1(ROI, 100, 100, 400, 500) # 定义检测区域
reduce_domain(GrayImage, ROI, ImageReduced)
create_shape_model(ImageReduced, 5, 0, 2*np.pi, 'auto',
'use_polarity', 'auto', 'auto', ModelID)
# === 3. 异常检测与量化 ===
find_shape_model(GrayImage, ModelID, 0, 2*np.pi, 0.5,
1, 0.5, 'least_squares', 5, 0.9,
Row, Column, Angle, Score)
similarity = Score[0] # 获取主匹配得分
# === 4. 异常诊断处理流程 ===
if similarity < -0.6: # 阈值设定
# 视觉化异常区域
gen_cross(Cross, Row, Column, 25, Angle)
area_holes(ImageReduced, Area)
dev_set_color('red')
dev_display(Cross)
# 记录异常数据 [引用2: 监测系统集成]
timestamp = time.strftime("%Y%m%d-%H%M%S")
write_string(FileHandle, f'{timestamp}, {similarity}, Abnormal\n')
# 触发警报协议
set_alarm_light('red', 'blink')
send_remote_alert(f'ALERT: qo2ul异常 相似度{similarity}')
return {
'status': 'FAIL',
'similarity': float(similarity),
'coordinates': (int(Row), int(Column)),
'timestamp': timestamp
}
else:
return {'status': 'PASS', 'similarity': float(similarity)}
except Exception as e:
# 错误处理模块
log_error(f'[EXCEPTION] {str(e)}')
return {'status': 'ERROR', 'message': str(e)}
finally:
# 资源释放
clear_shape_model(ModelID)
close_framegrabber(AcqHandle)
if __name__ == "__main__":
# 初始化工业相机
open_framegrabber('GigEVision', 0, 0, 0, 0, 0, 0, 'default',
-1, 'default', -1, 'false', 'default',
'camera1', 0, -1, AcqHandle)
# 创建监测日志
open_file('device_log.csv', 'append', FileHandle)
write_string(FileHandle, "timestamp,similarity,status\n")
# 持续监测循环
while True:
result = qo2ul_device_monitoring_solution()
print(f"当前状态: {result['status']} 相似度: {result.get('similarity', 0):.4f}")
time.sleep(1) # 采样间隔
# 配置参数
wx_groupName = '星海预警' # 微信群名
wx_context = '星系警告!!!出现红白,注意规避---赶紧跑,收你的来了' # 微信消息
conVal = 2 # 执行间隔(秒)
path = 'D:/EVE_A_Eye-main/EVE_A_Eye' # 主目录
# 确保目录存在
if not os.path.exists(path):
os.makedirs(path)
print(f"已创建目录: {path}")
# 模拟器配置 - 新增了5558端口模拟器[^3]
devices = {
'qo2ul': ['127.0.0.1:5555', False],
'56': ['127.0.0.1:5557', False],
'y5c': ['127.0.0.1:5559', False] # 新增的59模拟器
}
gameSendPosition = {
'第二频道': '38 117',
'第三频道': '38 170',
'第四频道': '38 223',
'第五频道': '38 278',
'第六频道': '38 332',
'第七频道': '38 382'
}
sendTo = gameSendPosition['第六频道']
mutex = threading.Lock()
def setClipboardFile(img_path):
"""将图片复制到剪贴板"""
try:
im = Image.open(img_path)
temp_path = os.path.join(path, 'temp.bmp')
im.save(temp_path)
# 使用绝对路径加载图片
aString = windll.user32.LoadImageW(
0,
os.path.abspath(temp_path),
win32con.IMAGE_BITMAP,
0, 0,
win32con.LR_LOADFROMFILE
)
if aString != 0:
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardData(win32con.CF_BITMAP, aString)
win32clipboard.CloseClipboard()
return True
except (UnidentifiedImageError, FileNotFoundError) as e:
print(f"剪贴板错误: {e}")
return False
def send_msg(content, msg_type=1):
"""发送微信消息"""
try:
wechatWindow = auto.WindowControl(
searchDepth=1, Name=f"{wx_groupName}")
wechatWindow.SetActive()
edit = wechatWindow.EditControl()
if msg_type == 1: # 文本
auto.SetClipboardText(content)
edit.SendKeys('{Ctrl}v')
edit.SendKeys('{Enter}')
elif msg_type in [2, 3]: # 图片
if setClipboardFile(content):
edit.SendKeys('{Ctrl}v')
edit.SendKeys('{Enter}')
else:
print(f"图片发送失败: {content}")
except Exception as e:
print(f"微信消息发送异常: {e}")
def Start():
"""初始化程序"""
# 确保目录存在
if not os.path.exists(path):
os.makedirs(path)
# 初始化图片文件
template_dir = os.path.join(path, 'tem')
os.makedirs(template_dir, exist_ok=True)
# 创建占位文件
placeholder_files = [
('list.png', 'new_{}_list.png'),
('playerList.png', 'old_{}_playerList.png'),
('playerList.png', 'new_{}_playerList.png')
]
for src, dest_pattern in placeholder_files:
src_path = os.path.join(template_dir, src)
if not os.path.exists(src_path):
Image.new('RGB', (50, 50), color='black').save(src_path)
for device in devices: # 为所有设备创建文件
dest_path = os.path.join(path, dest_pattern.format(device))
if not os.path.exists(dest_path):
Image.open(src_path).save(dest_path)
# 启动监听线程 - 每个设备独立线程[^3]
for device in devices:
t = threading.Thread(target=Listening, args=(device,))
t.start()
print('预警系统已启动')
context = f"预警系统已上线,监测星系列表:\n {list(devices.keys())}"
send_msg(context, msg_type=1)
def screenc(device_tag, num):
"""截取设备屏幕并保存到指定路径"""
device_addr = devices[device_tag][0]
filename = os.path.join(path, f"{device_tag}_{num}.png")
# ADB截图命令 - 支持多设备[^3]
command = f'adb -s {device_addr} exec-out screencap -p > "{filename}"'
os.system(command)
# 验证截图是否生成
if not os.path.exists(filename):
print(f"截图失败: {filename}")
return False
return True
def crop(x1, y1, x2, y2, input_path, output_path):
"""裁剪图片"""
try:
img = Image.open(input_path)
cropped = img.crop((x1, y1, x2, y2))
cropped.save(output_path)
img.close()
return True
except Exception as e:
print(f"图片裁剪错误: {e}")
return False
def LoadImage(img1, img2):
"""加载图像"""
try:
i1 = cv2.imread(img1, 0)
i2 = cv2.imread(img2, 0)
return i1, i2
except Exception as e:
print(f"图像加载错误: {e}")
return None, None
def CompareImages(img1, img2):
"""图像相似度比较"""
try:
res = cv2.matchTemplate(img1, img2, cv2.TM_CCOEFF_NORMED)
_, max_val, _, _ = cv2.minMaxLoc(res)
return max_val
except:
return 0.0
def SendGameMessage(device_tag):
"""游戏内发送消息"""
addr = devices[device_tag][0]
commands = [
'shell input tap 211 478',
f'shell input tap {sendTo}',
'shell input tap 266 520',
'shell input tap 870 511',
'shell input tap 68 292',
'shell input tap 250 350',
'shell input tap 250 433',
'shell input tap 344 190',
'shell input tap 342 512'
]
for cmd in commands:
os.system(f'adb -s {addr} {cmd}') # 针对特定设备执行命令
time.sleep(0.2)
def SendWeChat(device_tag):
"""发送微信预警"""
if not wx_groupName:
return
img_path = os.path.join(path, f"{device_tag}_2.png")
if not os.path.exists(img_path):
print(f"预警图片不存在: {img_path}")
return
mutex.acquire()
try:
# 发送图片
send_msg(img_path, msg_type=3)
print(f"已发送{device_tag}预警图片")
# 发送文本
context = f"{wx_context} - [{device_tag}]"
send_msg(context, msg_type=1)
finally:
mutex.release()
def Listening(device_tag):
"""监控线程 - 每个设备独立运行[^3]"""
def secondary_task():
"""二级检测任务"""
while True:
# 执行截图
screenshot_path = os.path.join(path, f"{device_tag}_1.png")
if not screenc(device_tag, 1):
time.sleep(4)
continue
# 裁剪检测区域
list_img_path = os.path.join(path, f"new_{device_tag}_list.png")
crop(918, 44, 956, 153, screenshot_path, list_img_path)
# 加载比对图像
template_path = os.path.join(path, "tem", "list.png")
img_current = cv2.imread(list_img_path, 0)
img_template = cv2.imread(template_path, 0)
if img_current is None or img_template is None:
time.sleep(2)
continue
# 图像相似度检测
similarity = CompareImages(img_current, img_template)
if similarity < 0.10: # 检测到舰船列表有人
print(f"{device_tag}监测异常 - 相似度: {similarity:.4f}")
SendWeChat(device_tag)
# 更新缓存
cv2.imwrite(
os.path.join(path, f"old_{device_tag}_playerList.png"),
img_current,
[cv2.IMWRITE_PNG_COMPRESSION, 0]
)
time.sleep(40)
else:
time.sleep(conVal)
# 启动二级检测线程
threading.Thread(target=secondary_task).start()
# 主检测循环
while True:
# 执行截图
screenshot_path = os.path.join(path, f"{device_tag}_2.png")
if not screenc(device_tag, 2):
time.sleep(conVal)
continue
# 裁剪玩家列表区域
player_img_path = os.path.join(path, f"new_{device_tag}_playerList.png")
crop(774, 502, 956, 537, screenshot_path, player_img_path)
# 加载比对图像
img_current = cv2.imread(player_img_path, 0)
img_cache = cv2.imread(os.path.join(path, f"old_{device_tag}_playerList.png"), 0)
if img_current is None or img_cache is None:
time.sleep(conVal)
continue
# 图像相似度检测
similarity = CompareImages(img_current, img_cache)
if similarity < 0.9: # 检测到本地频道变化
print(f"{device_tag}本地频道警告 - 相似度: {similarity:.4f}")
SendGameMessage(device_tag)
# 更新缓存
cv2.imwrite(
os.path.join(path, f"old_{device_tag}_playerList.png"),
img_current,
[cv2.IMWRITE_PNG_COMPRESSION, 0]
)
time.sleep(5)
else:
time.sleep(conVal)
# 启动程序
if __name__ == "__main__":
Start()
最新发布