当前位置: 首页 > news >正文

yolo自动化项目实例解析(九) 导航

比如我们经常使用的导航,说白了就是寻找两点之间最近的路径,也就是所谓的寻路,我们需要想办法让程序知道他要去哪里,路径包含(起点、轨迹、终点)

一、录制轨迹

从平面角度来看,我们可以把区域视为一张大地图,而我们当前区域附近的区域视为小地图,当我们在大地图中的区域时,我们需要根据当前的区域位置来判断一下当前位于大地图中的什么坐标,首先我们就需要根据大小地图去定位坐标

1、sift特征匹配算法

该函数使用 SIFT(Scale-Invariant Feature Transform,尺度不变特征变换)算法来在一张大图(big_img)中寻找另一张小图(small_img)的位置。SIFT 是一种用于图像处理和计算机视觉领域的特征检测算法,它能够识别出图像中的关键点,并且这些关键点对光照变化、旋转等具有一定的不变性。

    def find_img_all_sift(self, big_img, small_img, roi):"""使用 SIFT 特征匹配在大图中找到小图的匹配位置:param big_img: 大图:param small_img: 小图:param roi: 感兴趣区域 (ROI):return: 匹配结果列表"""# 使用 SIFT 特征匹配sift = cv2.SIFT_create()kp1, des1 = sift.detectAndCompute(big_img, None)kp2, des2 = sift.detectAndCompute(small_img, None)# 确保描述符类型为 float32des1 = des1.astype(np.float32)des2 = des2.astype(np.float32)bf = cv2.BFMatcher()matches = bf.knnMatch(des1, des2, k=2)good = []for m, n in matches:if m.distance < 0.75 * n.distance:good.append([m])if len(good) > 10:src_pts = np.float32([kp1[m[0].queryIdx].pt for m in good]).reshape(-1, 1, 2)dst_pts = np.float32([kp2[m[0].trainIdx].pt for m in good]).reshape(-1, 1, 2)M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)h, w = small_img.shape[:2]pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)dst = cv2.perspectiveTransform(pts, M)return [{"result": tuple(map(int, dst[0][0])), "rectangle": [tuple(map(int, p[0])) for p in dst]}]return []

就是大图匹配小图坐标

使用案例
import cv2
import numpy as npdef find_img_all_sift(big_img, small_img, roi=None):"""使用 SIFT 特征匹配在大图中找到小图的匹配位置:param big_img: 大图:param small_img: 小图:param roi: 感兴趣区域 (ROI),默认为None表示整个图像:return: 匹配结果列表"""# 使用 SIFT 特征匹配sift = cv2.SIFT_create()kp1, des1 = sift.detectAndCompute(big_img, None)kp2, des2 = sift.detectAndCompute(small_img, None)# 确保描述符类型为 float32des1 = des1.astype(np.float32)des2 = des2.astype(np.float32)bf = cv2.BFMatcher()matches = bf.knnMatch(des1, des2, k=2)good = []for m, n in matches:if m.distance < 0.75 * n.distance:good.append([m])if len(good) > 10:src_pts = np.float32([kp1[m[0].queryIdx].pt for m in good]).reshape(-1, 1, 2)dst_pts = np.float32([kp2[m[0].trainIdx].pt for m in good]).reshape(-1, 1, 2)M, mask = cv2.findHomography(dst_pts, src_pts, cv2.RANSAC, 5.0)h, w = small_img.shape[:2]pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)dst = cv2.perspectiveTransform(pts, M)rectangle = [tuple(map(int, p[0])) for p in dst]center_x = int(sum(p[0] for p in rectangle) / 4)center_y = int(sum(p[1] for p in rectangle) / 4)return [{"result": tuple(map(int, dst[0][0])), "rectangle": rectangle, "center": (center_x, center_y)}]return []# 加载图像
big_image_path = 'datu.png'
small_image_path = 'xiaotu.png'big_image = cv2.imread(big_image_path, cv2.IMREAD_GRAYSCALE)
small_image = cv2.imread(small_image_path, cv2.IMREAD_GRAYSCALE)# 验证图像是否成功加载
if big_image is None:raise FileNotFoundError(f"无法加载大图: {big_image_path}")
if small_image is None:raise FileNotFoundError(f"无法加载小图: {small_image_path}")# 调用函数
results = find_img_all_sift(big_image, small_image, None)
for result in results:print(f"匹配点坐标 {result['result']}   匹配点4个顶点坐标 {result['rectangle']}   中心点坐标 {result['center']}")
绘制小图在大图中的坐标
# 在原图上绘制矩形框和中心点
big_image_color = cv2.cvtColor(big_image, cv2.COLOR_GRAY2BGR)
for result in results:rectangle = result['rectangle']center = result['center']#绘制框架cv2.polylines(big_image_color, [np.array(rectangle)], True, (0, 255, 0), 2)#绘制中心红点cv2.circle(big_image_color, center, 5, (0, 0, 255), -1)  # 显示结果
cv2.imshow('Matched Locations', big_image_color)
cv2.waitKey(0)
cv2.destroyAllWindows()

思路

首先我们先详细怎么才能实现寻路功能

寻路,顾名思义就是寻找正确到达目标的一个路径,但是怎么能让机器知道我们要去哪里呢,
就是通过不断的给他新的坐标,然后进行移动

坐标怎么获取我们上面已经研究过了,通过大图和小图的特征进行匹配截图

我们小图可以看作是我们游戏中的小地图,众所周知,大部分游戏的小地图都是一个轮盘样式的,固定在某个区域内,当我们人物移动的时候,人物会在小地图上的坐标会发生偏移,也就是说我们可以视为,人物本身没有变化,而地图发生了拖拽,小地图在大地图中的坐标发生了偏移

我们上面拿到了小地图在大地图中的坐标和中心点, 我们可以通过在屏幕中循环截取小地图的坐标变化,从而保留出人物在大地图上的运行轨迹

2、图片截取

我们小地图的区域是会不断变化的,我们不可能准备所有区域的小地图,更加希望是在实时获取当前小地图中的信息然后再去做判断,通过这个方法去截取指定区域的图片作为小地图用于识别

import ctypes
import cv2
import numpy as np
import win32gui
import win32uidef screenshot(hwnd, left, top, right, bottom):# 获取窗口设备上下文hwndDC = win32gui.GetWindowDC(hwnd)mfcDC = win32ui.CreateDCFromHandle(hwndDC)saveDC = mfcDC.CreateCompatibleDC()# 获取窗口大小rect = win32gui.GetWindowRect(hwnd)width = right - leftheight = bottom - top# 创建位图saveBitMap = win32ui.CreateBitmap()saveBitMap.CreateCompatibleBitmap(mfcDC, width, height)saveDC.SelectObject(saveBitMap)# 设置剪切区域saveDC.SetWindowExt((width, height))saveDC.SetViewportExt((width, height))saveDC.SetWindowOrg((left, top))saveDC.SetViewportOrg((0, 0))# 截图result = ctypes.windll.user32.PrintWindow(hwnd, saveDC.GetSafeHdc(), 0)if result == 0:print("PrintWindow failed")return Nonebmpinfo = saveBitMap.GetInfo()bmpstr = saveBitMap.GetBitmapBits(True)# 转换为 OpenCV 图像im_cv = np.frombuffer(bmpstr, dtype='uint8')im_cv = im_cv.reshape((height, width, 4))# 清理资源win32gui.DeleteObject(saveBitMap.GetHandle())saveDC.DeleteDC()mfcDC.DeleteDC()win32gui.ReleaseDC(hwnd, hwndDC)return im_cv[:, :, :3]  # 去掉 alpha 通道# 定义
hwnd = 65800  # 桌面句柄
map_region = (100, 100, 200, 200)  # 左  上  右  下
left, top, right, bottom = map_region
small_img = screenshot(hwnd, left, top, right, bottom)# 保存截图
output_path = "screenshot.png"
cv2.imwrite(output_path, small_img)
print(f"截图已保存到: {output_path}")

3、截图坐标判定

我们截取到的图片是一个区域的矩形,我们需要先获取出矩形的中心点,这个中心点也被视为我们自身当前的位置

import time
import pyautoguidef get_screenshot_area(center_x, center_y, width, height):"""根据中心点和宽高计算截图区域:param center_x: 中心点的 x 坐标:param center_y: 中心点的 y 坐标:param width: 截图区域的宽度:param height: 截图区域的高度:return: (left, top, right, bottom)"""half_width = width // 2half_height = height // 2left = center_x - half_widthtop = center_y - half_heightright = center_x + half_widthbottom = center_y + half_heightreturn left, top, right, bottomdef main():# 等待2秒time.sleep(2)# 获取鼠标当前位置mouse_x, mouse_y = pyautogui.position()print(f"鼠标位置: ({mouse_x}, {mouse_y})")# 计算截图区域(这里指定的截图的矩形大小)width = 80  # 你可以根据需要调整宽度height = 80  # 你可以根据需要调整高度left, top, right, bottom = get_screenshot_area(mouse_x, mouse_y, width, height)print(f"截图区域: ({left}, {top}, {right}, {bottom})")if __name__ == "__main__":main()

4、截图与特征匹配

结合上面的代码,当我们当前区域的小地图发生位置变化的时候,会记录下所有在大地图上的坐标

import timeimport cv2
import numpy as npdef find_img_all_sift(big_img, small_img, roi=None):"""使用 SIFT 特征匹配在大图中找到小图的匹配位置:param big_img: 大图:param small_img: 小图:param roi: 感兴趣区域 (ROI),默认为None表示整个图像:return: 匹配结果列表"""# 使用 SIFT 特征匹配sift = cv2.SIFT_create()kp1, des1 = sift.detectAndCompute(big_img, None)kp2, des2 = sift.detectAndCompute(small_img, None)# 确保描述符类型为 float32des1 = des1.astype(np.float32)des2 = des2.astype(np.float32)bf = cv2.BFMatcher()matches = bf.knnMatch(des1, des2, k=2)good = []for m, n in matches:if m.distance < 0.75 * n.distance:good.append([m])if len(good) > 10:src_pts = np.float32([kp1[m[0].queryIdx].pt for m in good]).reshape(-1, 1, 2)dst_pts = np.float32([kp2[m[0].trainIdx].pt for m in good]).reshape(-1, 1, 2)M, mask = cv2.findHomography(dst_pts, src_pts, cv2.RANSAC, 5.0)h, w = small_img.shape[:2]pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)dst = cv2.perspectiveTransform(pts, M)rectangle = [tuple(map(int, p[0])) for p in dst]center_x = int(sum(p[0] for p in rectangle) / 4)center_y = int(sum(p[1] for p in rectangle) / 4)return [{"result": tuple(map(int, dst[0][0])), "rectangle": rectangle, "center": (center_x, center_y)}]return []import ctypes
import cv2
import numpy as np
import win32gui
import win32uidef screenshot(hwnd, left, top, right, bottom):# 获取窗口设备上下文hwndDC = win32gui.GetWindowDC(hwnd)mfcDC = win32ui.CreateDCFromHandle(hwndDC)saveDC = mfcDC.CreateCompatibleDC()# 获取窗口大小rect = win32gui.GetWindowRect(hwnd)width = right - leftheight = bottom - top# 创建位图saveBitMap = win32ui.CreateBitmap()saveBitMap.CreateCompatibleBitmap(mfcDC, width, height)saveDC.SelectObject(saveBitMap)# 设置剪切区域saveDC.SetWindowExt((width, height))saveDC.SetViewportExt((width, height))saveDC.SetWindowOrg((left, top))saveDC.SetViewportOrg((0, 0))# 截图result = ctypes.windll.user32.PrintWindow(hwnd, saveDC.GetSafeHdc(), 0)if result == 0:print("PrintWindow failed")return Nonebmpinfo = saveBitMap.GetInfo()bmpstr = saveBitMap.GetBitmapBits(True)# 转换为 OpenCV 图像im_cv = np.frombuffer(bmpstr, dtype='uint8')im_cv = im_cv.reshape((height, width, 4))# 清理资源win32gui.DeleteObject(saveBitMap.GetHandle())saveDC.DeleteDC()mfcDC.DeleteDC()win32gui.ReleaseDC(hwnd, hwndDC)return im_cv[:, :, :3]  # 去掉 alpha 通道#定义截图的句柄、窗口大小
hwnd = 65800  # 桌面句柄
map_region = (100, 100, 200, 200)  # 左  上  右  下
left, top, right, bottom = map_region
#定义大地图
datu = 'datu.png'
#格式化地图为NumPy 数组
big_image = cv2.imread(datu, cv2.IMREAD_GRAYSCALE)while True:time.sleep(2)# 获取截取的小地图(获取的已经是NumPy 数组不需要再转换)small_image = screenshot(hwnd, left, top, right, bottom)# #匹配大小地图的特征results = find_img_all_sift(big_image, small_image, None)#变量输出参数for result in results:print(f"匹配点坐标 {result['result']}   匹配点4个顶点坐标 {result['rectangle']}   中心点坐标 {result['center']}")

5、录制区域检查

我们绘制路径的时候一定不希望在切换窗口的时候依旧在绘制,这样会存在大量的误差,我们更希望在立刻指定窗口后暂停录制,下面做个判断

import timeimport cv2
import numpy as np
import win32apidef find_img_all_sift(big_img, small_img, roi=None):"""使用 SIFT 特征匹配在大图中找到小图的匹配位置:param big_img: 大图:param small_img: 小图:param roi: 感兴趣区域 (ROI),默认为None表示整个图像:return: 匹配结果列表"""# 使用 SIFT 特征匹配sift = cv2.SIFT_create()kp1, des1 = sift.detectAndCompute(big_img, None)kp2, des2 = sift.detectAndCompute(small_img, None)# 确保描述符类型为 float32des1 = des1.astype(np.float32)des2 = des2.astype(np.float32)bf = cv2.BFMatcher()matches = bf.knnMatch(des1, des2, k=2)good = []for m, n in matches:if m.distance < 0.75 * n.distance:good.append([m])if len(good) > 10:src_pts = np.float32([kp1[m[0].queryIdx].pt for m in good]).reshape(-1, 1, 2)dst_pts = np.float32([kp2[m[0].trainIdx].pt for m in good]).reshape(-1, 1, 2)M, mask = cv2.findHomography(dst_pts, src_pts, cv2.RANSAC, 5.0)h, w = small_img.shape[:2]pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)dst = cv2.perspectiveTransform(pts, M)rectangle = [tuple(map(int, p[0])) for p in dst]center_x = int(sum(p[0] for p in rectangle) / 4)center_y = int(sum(p[1] for p in rectangle) / 4)return [{"result": tuple(map(int, dst[0][0])), "rectangle": rectangle, "center": (center_x, center_y)}]return []import ctypes
import cv2
import numpy as np
import win32gui
import win32uidef screenshot(hwnd, left, top, right, bottom):# 获取窗口设备上下文hwndDC = win32gui.GetWindowDC(hwnd)mfcDC = win32ui.CreateDCFromHandle(hwndDC)saveDC = mfcDC.CreateCompatibleDC()# 获取窗口大小rect = win32gui.GetWindowRect(hwnd)width = right - leftheight = bottom - top# 创建位图saveBitMap = win32ui.CreateBitmap()saveBitMap.CreateCompatibleBitmap(mfcDC, width, height)saveDC.SelectObject(saveBitMap)# 设置剪切区域saveDC.SetWindowExt((width, height))saveDC.SetViewportExt((width, height))saveDC.SetWindowOrg((left, top))saveDC.SetViewportOrg((0, 0))# 截图result = ctypes.windll.user32.PrintWindow(hwnd, saveDC.GetSafeHdc(), 0)if result == 0:print("PrintWindow failed")return Nonebmpinfo = saveBitMap.GetInfo()bmpstr = saveBitMap.GetBitmapBits(True)# 转换为 OpenCV 图像im_cv = np.frombuffer(bmpstr, dtype='uint8')im_cv = im_cv.reshape((height, width, 4))# 清理资源win32gui.DeleteObject(saveBitMap.GetHandle())saveDC.DeleteDC()mfcDC.DeleteDC()win32gui.ReleaseDC(hwnd, hwndDC)return im_cv[:, :, :3]  # 去掉 alpha 通道#检查活动窗口
def get_window_handle_at_mouse_position():#获取当前活动窗口# active_hwnd = ctypes.windll.user32.GetForegroundWindow()# return active_hwndpoint = win32api.GetCursorPos()hwnd = win32gui.WindowFromPoint(point)return hwnddef main():hwnd = 65800   #窗口句柄map_region = (100, 100, 200, 200) #截图矩形left, top, right, bottom = map_region#定义大地图及格式化datu = 'datu.png'# 格式化地图为NumPy 数组big_image = cv2.imread(datu, cv2.IMREAD_GRAYSCALE)#循环截图匹配特征while True:#检查鼠标所在的窗口是否为指定的窗口id,不是就停止if get_window_handle_at_mouse_position() != hwnd:print("鼠标离开了指定窗口!")time.sleep(0.5)continuetime.sleep(2)# 获取截取的小地图(获取的已经是NumPy 数组不需要再转换)small_image = screenshot(hwnd, left, top, right, bottom)# #匹配大小地图的特征results = find_img_all_sift(big_image, small_image, None)#变量输出参数for result in results:print(f"匹配点坐标 {result['result']}   匹配点4个顶点坐标 {result['rectangle']}   中心点坐标 {result['center']}")if __name__ == '__main__':main()

6、导航运行轨迹

import time
import traceback
import cv2
import numpy as np
import win32api
import win32gui
import win32ui
import ctypesdef find_img_all_sift(big_img, small_img):"""使用 SIFT 特征匹配在大图中找到小图的匹配位置:param big_img: 大图:param small_img: 小图:return: 匹配结果列表"""# 使用 SIFT 特征匹配sift = cv2.SIFT_create()kp1, des1 = sift.detectAndCompute(big_img, None)kp2, des2 = sift.detectAndCompute(small_img, None)# 确保描述符类型为 float32des1 = des1.astype(np.float32)des2 = des2.astype(np.float32)bf = cv2.BFMatcher()matches = bf.knnMatch(des1, des2, k=2)good = []for m, n in matches:if m.distance < 0.75 * n.distance:good.append([m])if len(good) > 10:src_pts = np.float32([kp1[m[0].queryIdx].pt for m in good]).reshape(-1, 1, 2)dst_pts = np.float32([kp2[m[0].trainIdx].pt for m in good]).reshape(-1, 1, 2)M, mask = cv2.findHomography(dst_pts, src_pts, cv2.RANSAC, 5.0)h, w = small_img.shape[:2]pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)dst = cv2.perspectiveTransform(pts, M)rectangle = [tuple(map(int, p[0])) for p in dst]center_x = int(sum(p[0] for p in rectangle) / 4)center_y = int(sum(p[1] for p in rectangle) / 4)return [{"result": tuple(map(int, dst[0][0])), "rectangle": rectangle, "center": (center_x, center_y)}]return []def screenshot(hwnd, left, top, right, bottom):# 获取窗口设备上下文hwndDC = win32gui.GetWindowDC(hwnd)mfcDC = win32ui.CreateDCFromHandle(hwndDC)saveDC = mfcDC.CreateCompatibleDC()# 获取窗口大小rect = win32gui.GetWindowRect(hwnd)width = right - leftheight = bottom - top# 创建位图saveBitMap = win32ui.CreateBitmap()saveBitMap.CreateCompatibleBitmap(mfcDC, width, height)saveDC.SelectObject(saveBitMap)# 设置剪切区域saveDC.SetWindowExt((width, height))saveDC.SetViewportExt((width, height))saveDC.SetWindowOrg((left, top))saveDC.SetViewportOrg((0, 0))# 截图result = ctypes.windll.user32.PrintWindow(hwnd, saveDC.GetSafeHdc(), 0)if result == 0:print("PrintWindow failed")return Nonebmpinfo = saveBitMap.GetInfo()bmpstr = saveBitMap.GetBitmapBits(True)# 转换为 OpenCV 图像im_cv = np.frombuffer(bmpstr, dtype='uint8')im_cv = im_cv.reshape((height, width, 4))# 清理资源win32gui.DeleteObject(saveBitMap.GetHandle())saveDC.DeleteDC()mfcDC.DeleteDC()win32gui.ReleaseDC(hwnd, hwndDC)return im_cv[:, :, :3]  # 去掉 alpha 通道def get_window_handle_at_mouse_position():point = win32api.GetCursorPos()hwnd = win32gui.WindowFromPoint(point)return hwnddef main():hwnd = 65800  # 窗口句柄map_region = (100, 100, 200, 200)  # 截图矩形left, top, right, bottom = map_region# 定义大地图及格式化datu = 'datu.png'big_image = cv2.imread(datu, cv2.IMREAD_GRAYSCALE)big_img = cv2.imdecode(np.fromfile(file=datu, dtype=np.uint8), cv2.IMREAD_COLOR)  # 加载大图big_height, big_width, _ = big_img.shapebig_img_yt = big_img.copy()# 创建一个窗口来显示大图,并设置窗口大小cv2.namedWindow('Matched Image', cv2.WINDOW_NORMAL)cv2.resizeWindow('Matched Image', big_width, big_height)while True:# 检查鼠标所在的窗口是否为指定的窗口id, 不是就停止if get_window_handle_at_mouse_position() != hwnd:print("鼠标离开了指定窗口!")time.sleep(0.5)continuetime.sleep(2)# 获取截取的小地图(获取的已经是NumPy 数组不需要再转换)small_image = screenshot(hwnd, left, top, right, bottom)if small_image is not None:# 匹配大小地图的特征results = find_img_all_sift(big_image, small_image)print(results)# 在大图上标记匹配点for result in results:result_post = [result["center"][0], result["center"][1]]cv2.circle(big_img_yt, result_post, 2, (255, 0, 0), -1)# 显示标记后的图像cv2.imshow('Matched Image', big_img_yt)# 按 'q' 键退出if cv2.waitKey(1) & 0xFF == ord('q'):break# 释放资源cv2.destroyAllWindows()if __name__ == '__main__':main()

我们上面实时显示的时候发现,我们拖动图片向下,他就记录上面的坐标
反之,我们向上的时候他就记录向下的坐标 ,这里的圆心我们可以视为人物,当地图拖拽的时候我们人物进行移动

7、添加开关

import time
import traceback
import cv2
import keyboard
import numpy as np
import win32api
import win32gui
import win32ui
import ctypes
import threadingdef find_img_all_sift(big_img, small_img):"""使用 SIFT 特征匹配在大图中找到小图的匹配位置:param big_img: 大图:param small_img: 小图:return: 匹配结果列表"""# 使用 SIFT 特征匹配sift = cv2.SIFT_create()kp1, des1 = sift.detectAndCompute(big_img, None)kp2, des2 = sift.detectAndCompute(small_img, None)# 确保描述符类型为 float32des1 = des1.astype(np.float32)des2 = des2.astype(np.float32)bf = cv2.BFMatcher()matches = bf.knnMatch(des1, des2, k=2)good = []for m, n in matches:if m.distance < 0.75 * n.distance:good.append([m])if len(good) > 10:src_pts = np.float32([kp1[m[0].queryIdx].pt for m in good]).reshape(-1, 1, 2)dst_pts = np.float32([kp2[m[0].trainIdx].pt for m in good]).reshape(-1, 1, 2)M, mask = cv2.findHomography(dst_pts, src_pts, cv2.RANSAC, 5.0)h, w = small_img.shape[:2]pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)dst = cv2.perspectiveTransform(pts, M)rectangle = [tuple(map(int, p[0])) for p in dst]center_x = int(sum(p[0] for p in rectangle) / 4)center_y = int(sum(p[1] for p in rectangle) / 4)return [{"result": tuple(map(int, dst[0][0])), "rectangle": rectangle, "center": (center_x, center_y)}]return []def screenshot(hwnd, left, top, right, bottom):# 获取窗口设备上下文hwndDC = win32gui.GetWindowDC(hwnd)mfcDC = win32ui.CreateDCFromHandle(hwndDC)saveDC = mfcDC.CreateCompatibleDC()# 获取窗口大小rect = win32gui.GetWindowRect(hwnd)width = right - leftheight = bottom - top# 创建位图saveBitMap = win32ui.CreateBitmap()saveBitMap.CreateCompatibleBitmap(mfcDC, width, height)saveDC.SelectObject(saveBitMap)# 设置剪切区域saveDC.SetWindowExt((width, height))saveDC.SetViewportExt((width, height))saveDC.SetWindowOrg((left, top))saveDC.SetViewportOrg((0, 0))# 截图result = ctypes.windll.user32.PrintWindow(hwnd, saveDC.GetSafeHdc(), 0)if result == 0:print("PrintWindow failed")return Nonebmpinfo = saveBitMap.GetInfo()bmpstr = saveBitMap.GetBitmapBits(True)# 转换为 OpenCV 图像im_cv = np.frombuffer(bmpstr, dtype='uint8')im_cv = im_cv.reshape((height, width, 4))# 清理资源win32gui.DeleteObject(saveBitMap.GetHandle())saveDC.DeleteDC()mfcDC.DeleteDC()win32gui.ReleaseDC(hwnd, hwndDC)return im_cv[:, :, :3]  # 去掉 alpha 通道def get_window_handle_at_mouse_position():point = win32api.GetCursorPos()hwnd = win32gui.WindowFromPoint(point)return hwnddef main():hwnd = 65800  # 窗口句柄map_region = (100, 100, 200, 200)  # 截图矩形left, top, right, bottom = map_region# 定义大地图及格式化datu = 'datu.png'big_image = cv2.imread(datu, cv2.IMREAD_GRAYSCALE)big_img = cv2.imdecode(np.fromfile(file=datu, dtype=np.uint8), cv2.IMREAD_COLOR)  # 加载大图big_height, big_width, _ = big_img.shapebig_img_yt = big_img.copy()# 创建一个窗口来显示大图,并设置窗口大小cv2.namedWindow('Matched Image', cv2.WINDOW_NORMAL)cv2.resizeWindow('Matched Image', big_width, big_height)# 使用 threading.Event 来管理录制状态recording_event = threading.Event()def start_recording():recording_event.set()print("开始录制...")def stop_recording():recording_event.clear()print("停止录制...")# 注册按键监听keyboard.add_hotkey('f7', start_recording)keyboard.add_hotkey('f8', stop_recording)while True:# 检查鼠标所在的窗口是否为指定的窗口id, 不是就停止if get_window_handle_at_mouse_position() != hwnd:print("鼠标离开了指定窗口!")time.sleep(0.5)continuetime.sleep(2)# 基于按键判断if recording_event.is_set():print(111)# 获取截取的小地图(获取的已经是NumPy 数组不需要再转换)small_image = screenshot(hwnd, left, top, right, bottom)if small_image is not None:# 匹配大小地图的特征results = find_img_all_sift(big_image, small_image)print(results)# 在大图上标记匹配点for result in results:result_post = [result["center"][0], result["center"][1]]cv2.circle(big_img_yt, result_post, 2, (255, 0, 0), -1)# 显示标记后的图像cv2.imshow('Matched Image', big_img_yt)# 按 'q' 键退出if cv2.waitKey(1) & 0xFF == ord('q'):break# 释放资源cv2.destroyAllWindows()if __name__ == '__main__':main()

8、去除动态显示,添加保存轨迹图

import time
import traceback
import cv2
import keyboard
import numpy as np
import win32api
import win32gui
import win32ui
import ctypes
import threadingdef find_img_all_sift(big_img, small_img):"""使用 SIFT 特征匹配在大图中找到小图的匹配位置:param big_img: 大图:param small_img: 小图:return: 匹配结果列表"""# 使用 SIFT 特征匹配sift = cv2.SIFT_create()kp1, des1 = sift.detectAndCompute(big_img, None)kp2, des2 = sift.detectAndCompute(small_img, None)# 确保描述符类型为 float32des1 = des1.astype(np.float32)des2 = des2.astype(np.float32)bf = cv2.BFMatcher()matches = bf.knnMatch(des1, des2, k=2)good = []for m, n in matches:if m.distance < 0.75 * n.distance:good.append([m])if len(good) > 10:src_pts = np.float32([kp1[m[0].queryIdx].pt for m in good]).reshape(-1, 1, 2)dst_pts = np.float32([kp2[m[0].trainIdx].pt for m in good]).reshape(-1, 1, 2)M, mask = cv2.findHomography(dst_pts, src_pts, cv2.RANSAC, 5.0)h, w = small_img.shape[:2]pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)dst = cv2.perspectiveTransform(pts, M)rectangle = [tuple(map(int, p[0])) for p in dst]center_x = int(sum(p[0] for p in rectangle) / 4)center_y = int(sum(p[1] for p in rectangle) / 4)return [{"result": tuple(map(int, dst[0][0])), "rectangle": rectangle, "center": (center_x, center_y)}]return []def screenshot(hwnd, left, top, right, bottom):# 获取窗口设备上下文hwndDC = win32gui.GetWindowDC(hwnd)mfcDC = win32ui.CreateDCFromHandle(hwndDC)saveDC = mfcDC.CreateCompatibleDC()# 获取窗口大小rect = win32gui.GetWindowRect(hwnd)width = right - leftheight = bottom - top# 创建位图saveBitMap = win32ui.CreateBitmap()saveBitMap.CreateCompatibleBitmap(mfcDC, width, height)saveDC.SelectObject(saveBitMap)# 设置剪切区域saveDC.SetWindowExt((width, height))saveDC.SetViewportExt((width, height))saveDC.SetWindowOrg((left, top))saveDC.SetViewportOrg((0, 0))# 截图result = ctypes.windll.user32.PrintWindow(hwnd, saveDC.GetSafeHdc(), 0)if result == 0:print("PrintWindow failed")return Nonebmpinfo = saveBitMap.GetInfo()bmpstr = saveBitMap.GetBitmapBits(True)# 转换为 OpenCV 图像im_cv = np.frombuffer(bmpstr, dtype='uint8')im_cv = im_cv.reshape((height, width, 4))# 清理资源win32gui.DeleteObject(saveBitMap.GetHandle())saveDC.DeleteDC()mfcDC.DeleteDC()win32gui.ReleaseDC(hwnd, hwndDC)return im_cv[:, :, :3]  # 去掉 alpha 通道def get_window_handle_at_mouse_position():point = win32api.GetCursorPos()hwnd = win32gui.WindowFromPoint(point)return hwnddef main():hwnd = 65800  # 窗口句柄map_region = (100, 100, 200, 200)  # 截图矩形left, top, right, bottom = map_region# 定义大地图及格式化datu = 'datu.png'big_image = cv2.imread(datu, cv2.IMREAD_GRAYSCALE)big_img = cv2.imdecode(np.fromfile(file=datu, dtype=np.uint8), cv2.IMREAD_COLOR)  # 加载大图big_height, big_width, _ = big_img.shapebig_img_yt = big_img.copy()# 使用 threading.Event 来管理录制状态recording_event = threading.Event()def start_recording():recording_event.set()print("开始录制...")def stop_recording():recording_event.clear()print("停止录制...")# 保存带有标记的图片cv2.imwrite('111.png', big_img_yt)print("图片已保存为 111.png")# 注册按键监听keyboard.add_hotkey('f7', start_recording)keyboard.add_hotkey('f8', stop_recording)while True:# 检查鼠标所在的窗口是否为指定的窗口id, 不是就停止if get_window_handle_at_mouse_position() != hwnd:print("鼠标离开了指定窗口!")time.sleep(0.5)continuetime.sleep(2)# 基于按键判断if recording_event.is_set():print(111)# 获取截取的小地图(获取的已经是NumPy 数组不需要再转换)small_image = screenshot(hwnd, left, top, right, bottom)if small_image is not None:# 匹配大小地图的特征results = find_img_all_sift(big_image, small_image)print(results)# 在大图上标记匹配点for result in results:result_post = [result["center"][0], result["center"][1]]cv2.circle(big_img_yt, result_post, 2, (255, 0, 0), -1)# 释放资源cv2.destroyAllWindows()if __name__ == '__main__':main()

9、基于轨迹查询坐标

我们关于标记还需要做一个改变,就是每次循环的时候,不是都会标记当前图片的点位,因为我可能这次循环的时候坐标没有发生变化,所以我需要判断只有坐标发生变化的时候才会在图中进行标记,而且当第一次进行标记的时候使用绿色标记,当录制结束的时候,最后一次标记的时候使用红色标记,而两次标记中间的标记都使用蓝色

并且红色和绿色的标记都置顶,不会被覆盖

import time
import traceback
import cv2
import keyboard
import numpy as np
import win32api
import win32gui
import win32ui
import ctypes
import threadingdef find_img_all_sift(big_img, small_img):"""使用 SIFT 特征匹配在大图中找到小图的匹配位置:param big_img: 大图:param small_img: 小图:return: 匹配结果列表"""# 使用 SIFT 特征匹配sift = cv2.SIFT_create()kp1, des1 = sift.detectAndCompute(big_img, None)kp2, des2 = sift.detectAndCompute(small_img, None)# 确保描述符类型为 float32des1 = des1.astype(np.float32)des2 = des2.astype(np.float32)bf = cv2.BFMatcher()matches = bf.knnMatch(des1, des2, k=2)good = []for m, n in matches:if m.distance < 0.75 * n.distance:good.append([m])if len(good) > 10:src_pts = np.float32([kp1[m[0].queryIdx].pt for m in good]).reshape(-1, 1, 2)dst_pts = np.float32([kp2[m[0].trainIdx].pt for m in good]).reshape(-1, 1, 2)M, mask = cv2.findHomography(dst_pts, src_pts, cv2.RANSAC, 5.0)h, w = small_img.shape[:2]pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)dst = cv2.perspectiveTransform(pts, M)rectangle = [tuple(map(int, p[0])) for p in dst]center_x = int(sum(p[0] for p in rectangle) / 4)center_y = int(sum(p[1] for p in rectangle) / 4)return [{"result": tuple(map(int, dst[0][0])), "rectangle": rectangle, "center": (center_x, center_y)}]return []def screenshot(hwnd, left, top, right, bottom):# 获取窗口设备上下文hwndDC = win32gui.GetWindowDC(hwnd)mfcDC = win32ui.CreateDCFromHandle(hwndDC)saveDC = mfcDC.CreateCompatibleDC()# 获取窗口大小rect = win32gui.GetWindowRect(hwnd)width = right - leftheight = bottom - top# 创建位图saveBitMap = win32ui.CreateBitmap()saveBitMap.CreateCompatibleBitmap(mfcDC, width, height)saveDC.SelectObject(saveBitMap)# 设置剪切区域saveDC.SetWindowExt((width, height))saveDC.SetViewportExt((width, height))saveDC.SetWindowOrg((left, top))saveDC.SetViewportOrg((0, 0))# 截图result = ctypes.windll.user32.PrintWindow(hwnd, saveDC.GetSafeHdc(), 0)if result == 0:print("PrintWindow failed")return Nonebmpinfo = saveBitMap.GetInfo()bmpstr = saveBitMap.GetBitmapBits(True)# 转换为 OpenCV 图像im_cv = np.frombuffer(bmpstr, dtype='uint8')im_cv = im_cv.reshape((height, width, 4))# 清理资源win32gui.DeleteObject(saveBitMap.GetHandle())saveDC.DeleteDC()mfcDC.DeleteDC()win32gui.ReleaseDC(hwnd, hwndDC)return im_cv[:, :, :3]  # 去掉 alpha 通道def get_window_handle_at_mouse_position():point = win32api.GetCursorPos()hwnd = win32gui.WindowFromPoint(point)return hwnddef main():hwnd = 65800  # 窗口句柄map_region = (100, 100, 200, 200)  # 截图矩形left, top, right, bottom = map_region# 定义大地图及格式化datu = 'datu.png'big_image = cv2.imread(datu, cv2.IMREAD_GRAYSCALE)big_img = cv2.imdecode(np.fromfile(file=datu, dtype=np.uint8), cv2.IMREAD_COLOR)  # 加载大图big_height, big_width, _ = big_img.shapebig_img_yt = big_img.copy()# 使用 threading.Event 来管理录制状态recording_event = threading.Event()# 记录上一次的坐标last_center = Nonefirst_mark = Truemarks = []  # 用于存储所有标记def start_recording():nonlocal first_markfirst_mark = Truerecording_event.set()print("开始录制...")def stop_recording():nonlocal last_center, first_markrecording_event.clear()print("停止录制...")# 获取最后一次的截图small_image = screenshot(hwnd, left, top, right, bottom)if small_image is not None:results = find_img_all_sift(big_image, small_image)if results:current_center = results[0]["center"]if last_center is None or last_center != current_center:marks.append((current_center, (0, 0, 255)))  # 红色标记last_center = current_center# 绘制所有标记for mark_center, color in marks:cv2.circle(big_img_yt, mark_center, 2, color, -1)# 保存带有标记的图片cv2.imwrite('111.png', big_img_yt)print("图片已保存为 111.png")# 注册按键监听keyboard.add_hotkey('f7', start_recording)keyboard.add_hotkey('f8', stop_recording)while True:# 检查鼠标所在的窗口是否为指定的窗口id, 不是就停止if get_window_handle_at_mouse_position() != hwnd:print("鼠标离开了指定窗口!")time.sleep(0.5)continuetime.sleep(2)# 基于按键判断if recording_event.is_set():# 获取截取的小地图(获取的已经是NumPy 数组不需要再转换)small_image = screenshot(hwnd, left, top, right, bottom)if small_image is not None:# 匹配大小地图的特征results = find_img_all_sift(big_image, small_image)print(results)if results:current_center = results[0]["center"]if last_center is None or last_center != current_center:# 标记点color = (255, 0, 0)  # 蓝色if first_mark:color = (0, 255, 0)  # 绿色first_mark = Falsemarks.append((current_center, color))last_center = current_center# 释放资源cv2.destroyAllWindows()if __name__ == '__main__':main()

二、基于轨迹获取坐标

三、校对方向

相关文章:

yolo自动化项目实例解析(九) 导航

比如我们经常使用的导航&#xff0c;说白了就是寻找两点之间最近的路径&#xff0c;也就是所谓的寻路&#xff0c;我们需要想办法让程序知道他要去哪里&#xff0c;路径包含&#xff08;起点、轨迹、终点&#xff09; 一、录制轨迹 从平面角度来看&#xff0c;我们可以把区域视…...

MySQL 报错:1137 - Can‘t reopen table

MySQL 报错&#xff1a;1137 - Can’t reopen table 1. 问题 对临时表查询&#xff1a; select a.ts_code,a.tsnum,b.tsnum from (select t.ts_code ,count(*) tsnum from tmp_table t group by t.ts_code having count(*) > 20 and count(*)< 50 ) a ,(select t.ts_…...

Bokeh实现大规模数据可视化的最佳实践

目录 引言 一、Bokeh简介 二、安装Bokeh 三、数据准备 四、性能优化 五、创建图表 六、添加交互功能 七、应用案例 八、高级技巧 九、总结 引言 在数据科学领域,数据可视化是一个至关重要的环节。通过可视化,我们可以直观地理解数据的特征和趋势,为数据分析和决策…...

HTMLCSS:比赛记分卡

效果演示 这段 HTML 和 CSS 代码创建了一个卡片式的体育比赛信息展示组件&#xff0c;用于显示篮球比赛的两个队伍名称、比赛时间、比分以及一些装饰性的视觉元素。 HTML <div class"card"><div data-status"inprogress" class"teams"…...

什么是 Faiss?

好的&#xff0c;我来详细解释 Faiss&#xff0c;它的用途、使用场景&#xff0c;以及如何安装和使用。 什么是 Faiss&#xff1f; Faiss 是由 Facebook AI Research 开发的一个开源库&#xff0c;专门用于高效的相似性搜索和聚类。它非常擅长在高维向量空间中进行快速搜索&a…...

【prism】遇到一个坑,分享!

背景 我通用prism的方式写了一个弹窗,弹窗绑定一个 Loaded 事件,但是Loaded事件一直不触发!!! 具体过程 我的loaded事件也是通过命令的方式绑定的: <i:Interaction.Triggers><i:EventTrigger EventName="Loaded...

vue制作代码比较工具

前两天朋友问我 有没有vue可以做一个json代码在线比较工具 我也是在网上搜了一下找到的 废话不说 直接上代码 采用 v3 pnpm i v-code-diff <div><CodeDiff:old-string"oldStr":new-string"newStr"output-format"side-by-side"/>…...

GPT系列文章

GPT系列文章 GPT1 GPT1是由OpenAI公司发表在2018年要早于我们之前介绍的所熟知的BERT系列文章。总结&#xff1a;GPT 是一种半监督学习&#xff0c;采用两阶段任务模型&#xff0c;通过使用无监督的 Pre-training 和有监督的 Fine-tuning 来实现强大的自然语言理解。在 Pre-t…...

Qt实现可拖拽的矩形

之前项目上需要用Qt来绘制可拖拽改变形状的矩形。看了Qt Graphics相关的内容&#xff0c;虽然对Qt怎么添加图元的有了些了解&#xff0c;但是具体如何实现拖拽效果&#xff0c;一时也没有什么好的想法。还好网上有人分享的例子&#xff0c;很受启发。后来又回顾了一下这部分的代…...

python爬虫初体验(五)—— 边学边玩小游戏

1. 打开浏览器 利用webbrowser 模块的 open()函数可以启动一个新浏览器&#xff0c;打开指定的 URL。 import webbrowser webbrowser.open(http://inventwithpython.com/) 2. 猜数字游戏 # -*- coding: utf-8 -*- # This is a guess the number game. import randomsecretN…...

学习日志015--python单链表

创建 class Node:def __init__(self,data):# 数据域self.data data# 链接域self.next Noneclass LinkList:def __init__(self,):# 初始化头节点self.head None# 记录链表的长度self.size 0 增加 #头插def insert_head(self,value):# 创建新节点node Node(value)q self…...

51WORLD与南京水利研究院联合研发,国产数字孪生超融合一体机

近日&#xff0c;太湖流域水治理国际会议在江苏省无锡市举行。大会由水利部国际合作与科技司、河湖管理司、中国水利学会、水利部太湖流域管理局、无锡市人民政府、中国交通建设集团有限公司指导&#xff0c;南京水利科学研究院主办&#xff0c;以“践行新发展理念、推进流域水…...

自动泊车变自动撞车?小米SU7遭遇批量事故

科技新知 原创作者丨依蔓 编辑丨蕨影 小米系统bug&#xff0c;70多辆小米SU7同一天自动泊车撞墙、撞柱&#xff01; 近日&#xff0c;多名车主反映小米汽车SU7标准版“自动泊车”功能出现故障&#xff0c;造成不同程度的撞击、剐蹭损伤。 小米客服此前回应涉事车主&#xff0…...

异常和中断

在计算机系统中&#xff0c;异常和中断是两种常见的用于处理异步事件的机制。以下是常见的异常和中断及其特点的详细解释&#xff1a; 异常&#xff08;内中断&#xff09; 异常&#xff0c;也称为内中断&#xff0c;是由CPU内部事件引起的中断。异常通常与程序执行的当前指令…...

代理IP在后端开发中的应用与后端工程师的角色

目录 引言 代理IP的基本概念和工作原理 代理IP在后端开发中的应用 网络爬虫与数据采集 负载均衡与性能优化 安全防护与隐私保护 后端工程师在使用代理IP时面临的挑战 结论 引言 在数字化时代&#xff0c;网络技术的飞速发展极大地推动了各行各业的发展。其中&#xff…...

设计模式之 观察者模式

观察者模式&#xff08;Observer Pattern&#xff09;是一种行为型设计模式&#xff0c;它定义了一种一对多的依赖关系&#xff0c;让多个观察者对象同时监听一个主题对象&#xff08;Subject&#xff09;。当主题对象的状态发生变化时&#xff0c;所有依赖于它的观察者都会得到…...

SQLSever显示物理和逻辑 IO活动量的相关信息及显示分析、编译和执行各语句所需的毫秒数。

SQLSever SET STATISTICS IO显示物理和逻辑 IO活动量的相关信息及SET STATISTICS TIME显示分析、编译和执行各语句所需的毫秒数。 1、 SET STATISTICS IO (Transact-SQL) 物理 IO 与访问磁盘上的数据页相关&#xff0c;逻辑 IO 与访问内存中的数据页&#xff08;数据缓存&…...

CSS3 动画:前端开发的动态美

CSS3 动画:前端开发的动态美 CSS3 动画是现代网页设计中不可或缺的一部分,它为静态的网页元素添加了动态效果,提升了用户体验。本文将深入探讨CSS3动画的基础知识、高级技巧,并展示如何在实际项目中应用这些动画。 CSS3 动画基础 CSS3动画主要通过@keyframes和动画属性(…...

JavaWeb之综合案例

前言 这一节讲一个案例 1. 环境搭建 然后就是把这些数据全部用到sql语句中执行 2.查询所有-后台&前台 我们先写后台代码 2.1 后台 2.2 Dao BrandMapper&#xff1a; 注意因为数据库里面的名称是下划线分割的&#xff0c;我们类里面是驼峰的&#xff0c;所以要映射 …...

基于Spring Boot+Unipp的博物馆预约小程序(协同过滤算法、二维码识别)【原创】

&#x1f388;系统亮点&#xff1a;协同过滤算法、二维码识别&#xff1b; 一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构&#xff1a;B/S架构 运行环境&#xff1a;win10/win11、jdk17 前端&#xff1a; 技术&#xff1a;框…...

使用 Maven 构建一个简单的 Java 项目

Apache Maven 是一个强大的构建自动化工具&#xff0c;主要用于 Java 项目。它简化了构建和管理任何基于 Java 的项目的流程。 本指南将涵盖 Maven 的安装、设置一个简单的 Java 项目以及使用 Maven 运行该项目。 1. 安装 安装 Java 在安装 Maven 之前&#xff0c;需要确保…...

【51单片机】LCD1602液晶显示屏

学习使用的开发板&#xff1a;STC89C52RC/LE52RC 编程软件&#xff1a;Keil5 烧录软件&#xff1a;stc-isp 开发板实图&#xff1a; 文章目录 LCD1602存储结构时序结构 编码 —— 显示字符、数字 LCD1602 LCD1602&#xff08;Liquid Crystal Display&#xff09;液晶显示屏是…...

UDP协议

UDP&#xff08;UserDatagramProtocol&#xff09;是一个简单的传输层协议&#xff0c;特点&#xff1a;无连接、不可靠、面向数据包、全双工。 报文结构 1.源端口&#xff1a; 源端口号&#xff0c;需要对方回信时选用&#xff0c;不需要时全部置0. 2.目的端口&#xff1a;目…...

阅读 ADiffusion-Based Framework for Multi-Class Anomaly Detection

A Diffusion-Based Framework for Multi-Class Anomaly Detection 我觉得引言部分写的不错&#xff0c;将问题清楚的讲出来了&#xff0c;值得借鉴&#xff01;&#xff01; 摘要 基于重建的方法在异常检测方面取得了显著成果。最近流行的扩散模型的卓越图像重建能力引发了研…...

网络云计算】2024第47周-每日【2024/11/21】周考-实操题-RAID6实操解析1

文章目录 1、RAID6配置指南&#xff08;大致步骤&#xff09;2、注意事项3、截图和视频 网络云计算】2024第47周-每日【2024/11/21】周考-实操题-RAID6实操 RAID6是一种在存储系统中实现数据冗余和容错的技术&#xff0c;其最多可以容忍两块磁盘同时损坏而不造成数据丢失。RAID…...

ts- declare关键词及vue3报错“Window typeof globalThis”上不存在属性“nextLoading”、`

报错“Window & typeof globalThis”上不存在属性“nextLoading”、 代码环境&#xff1a;vue3、ts 阮一峰讲解 declarets 用法告诉编译器某个类型是存在的 下面的例子是脚本使用浏览器全局对象document。 declare var document; document.title "Hello";上面…...

【STM32】在 STM32 USB 设备库添加新的设备类

说实话&#xff0c;我非常想吐槽 STM32 的 USB device library&#xff0c;总感觉很混乱。 USB Device library architecture 根据架构图&#xff1a; Adding a custom class 如果你想添加新的设备类&#xff0c;必须修改的文件有 usbd_desc.cusbd_conf.cusb_device.c 需要…...

【单点知识】基于PyTorch讲解自动编码器(Autoencoder)

文章目录 0. 前言1. 自动编码器的基本概念1.1 定义1.2 目标1.3 结构 2. PyTorch实现自动编码器2.1 导入必要的库2.2 定义自动编码器模型2.3 加载数据2.4 训练自动编码器 3. 自动编码器的意义4. 自动编码器的应用4.1 图像处理4.2自然语言处理&#xff1a;4.3推荐系统&#xff1a…...

html+js实现图片的放大缩小等比缩放翻转,自动播放切换,顺逆时针旋转

效果图&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>图片预览</title><sty…...

【蓝桥杯C/C++】翻转游戏:多种实现与解法解析

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: 蓝桥杯C/C 文章目录 &#x1f4af;题目&#x1f4af;问题分析解法一&#xff1a;减法法解法二&#xff1a;位运算解法解法三&#xff1a;逻辑非解法解法四&#xff1a;条件运算符解法解法五&#xff1a;数组映射法不同解法的比较…...

介绍一下toupper(ch);函数(c基础)

hi , I am 36 适合对象c语言初学者 toupper(ch1); tolower(ch2); 是返回ch的大写或小写的字符但并不改变ch 若传递数字仍返回该数字 格式 #include<ctype.h> char res toupper(ch); 链接扫雷游戏代码分享(c基础)-CSDN博客 hi , I am 36. thanks for your look…...

如何使用Python代码实现给GPU预加热

如何使用Python代码实现给GPU预加热 一、引言二、使用深度学习框架进行预加热2.1 TensorFlow预加热2.2 PyTorch预加热三、使用CUDA进行预加热四、预加热的效果评估与优化五、结论与展望在高性能计算和深度学习领域,GPU(图形处理器)已经成为不可或缺的加速工具。然而,在实际…...

基于 SpringBoot 的作业管理系统【附源码】

基于 SpringBoot 的作业管理系统 效果如下&#xff1a; 系统注册页面 学生管理页面 作业管理页面 作业提交页面 系统管理员主页面 研究背景 随着社会的快速发展&#xff0c;信息技术的广泛应用已经渗透到各个行业。在教育领域&#xff0c;课程作业管理是学校教学活动中的重要…...

LeetCode题解:26.删除有序数组中的重复项【Python题解超详细,双指针法】,知识拓展:原地修改

题目描述 给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量为 k &…...

docker 容器运行Ruoyi-cloud

1&#xff0c;linux系统安装openjdk1.8,mvn,dokcer,node,git 2&#xff0c;拉取代码 1&#xff09;查看gitee仓库地址 2&#xff09;创建/app文件夹&#xff0c;进入app目录 mkdir /app cd /app 3&#xff09;clone代码 4&#xff09;修改配置文件中nacos地址 # 修改注…...

【Unity How】Unity中如何实现物体的匀速往返移动

直接上代码 using UnityEngine;public class CubeBouncePingPong : MonoBehaviour {[Header("移动参数")][Tooltip("移动速度")]public float moveSpeed 2f; // 控制移动的速度[Tooltip("最大移动距离")]public float maxDistance 5f; // 最大…...

STM32完全学习——系统时钟设置

一、时钟框图的解读 首先我们知道STM32在上电初始化之后使用的是内部的HSI未经过分频直接通过SW供给给系统时钟&#xff0c;由于内部HSI存在较大的误差&#xff0c;因此我们在系统完成上电初始化&#xff0c;之后需要将STM32的时钟切换到外部HSE作为系统时钟&#xff0c;那么我…...

简单理解下基于 Redisson 库的分布式锁机制

目录 简单理解下基于 Redisson 库的分布式锁机制代码流程&#xff1a;方法的调用&#xff1a;具体锁的实现&#xff1a;riderBalance 方法&#xff1a;tryLock 方法&#xff08;重载&#xff09;&#xff1a;tryLock 方法&#xff08;核心实现&#xff09;&#xff1a; 简单理解…...

ruoyi框架完成分库分表,按月自动建表功能

前提 这个分库分表功能&#xff0c;按月自动建表&#xff0c;做的比较久了&#xff0c;还没上线&#xff0c;是在ruoyi框架内做的&#xff0c;踩了不少坑&#xff0c;但是已经实现了&#xff0c;就分享一下代码吧 参考 先分享一些参考文章 【若依系列】集成ShardingSphere S…...

数据结构 【单链表练习】

今天来探讨两个练习题要使用的思想为快慢指针。 1、返回链表的中间节点 给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。如果有两个中间结点&#xff0c;则返回第二个中间结点。 整体思路如下图所示&#xff1a; 代码如下&#xff1a; /*** Definition f…...

wsl虚拟机中的dockers容器访问不了物理主机

1 首先保证wsl虚拟机能够访问宿主机IP地址&#xff0c;wsl虚拟机通过vEthernet (WSL)的地址访问&#xff0c;着意味着容器也要通过此IP地址访问物理主机。 2 遇到的问题&#xff1a;wsl虚拟机中安装了docker&#xff0c;用在用到docker容器内的开发环境&#xff0c;但是虚拟机…...

Elasticsearch 开放推理 API 增加了对 IBM watsonx.ai Slate 嵌入模型的支持

作者&#xff1a;来自 Elastic Saikat Sarkar 使用 Elasticsearch 向量数据库构建搜索 AI 体验时如何使用 IBM watsonx™ Slate 文本嵌入。 Elastic 很高兴地宣布&#xff0c;通过集成 IBM watsonx™ Slate 嵌入模型&#xff0c;我们的开放推理 API 功能得以扩展&#xff0c;这…...

【如何用更少的数据作出更好的决策】-gpt生成

如何用更少的数据作出更好的决策 用更少的数据作出更好的决策是一种能力的体现&#xff0c;需要结合有效的方法、严谨的逻辑以及对问题的深刻理解。以下是一些可以帮助你实现这一目标的策略&#xff1a; 明确目标 在收集和分析数据之前&#xff0c;先明确你的决策目标是什么…...

webview4/edgewebbrower学习记录——执行js

webview2可执行js方法&#xff1a;WVBrowser1.ExecuteScript(js, 1003) 参数1为js语句&#xff0c;参数2为命令号&#xff0c;执行完毕&#xff0c;会执行 procedure TBrowserFrame.WVBrowser1ExecuteScriptCompleted(Sender: TObject; aErrorCode: HRESULT; const aResultOb…...

Java文件上传解压

目录结构 工具类 枚举 定义文件类型 public enum FileType {// 未知UNKNOWN,// 压缩文件ZIP, RAR, _7Z, TAR, GZ, TAR_GZ, BZ2, TAR_BZ2,// 位图文件BMP, PNG, JPG, JPEG,// 矢量图文件SVG,// 影音文件AVI, MP4, MP3, AAR, OGG, WAV, WAVE}为了避免文件被修改后缀&#xff0…...

人工智能(AI)与机器学习(ML)基础知识

目录 1. 人工智能与机器学习的核心概念 什么是人工智能&#xff08;AI&#xff09;&#xff1f; 什么是机器学习&#xff08;ML&#xff09;&#xff1f; 什么是深度学习&#xff08;DL&#xff09;&#xff1f; 2. 机器学习的三大类型 &#xff08;1&#xff09;监督式学…...

autoware(2)运行自己的数据集

上一节完成了autoware.ai的安装和编译跑通了demo数据集&#xff0c;本将自己录制的数据包用于测试 1.修改点云地图 将加载点云地图的my_map.launch文件复制并命名为my_map_test.launch&#xff0c; &#xff08;1&#xff09;point cloud处替代原来的点云地图为自己的&#…...

HBase Java基础操作

Apache HBase 是一个开源的、分布式的、可扩展的大数据存储系统&#xff0c;它基于 Google 的 Bigtable 模型。使用 Java 操作 HBase 通常需要借助 HBase 提供的 Java API。以下是一个基本的示例&#xff0c;展示了如何在 Java 中连接到 HBase 并执行一些基本的操作&#xff0c…...

巧用观测云可用性监测(云拨测)

前言 做为系统运维或者开发&#xff0c;很多时候我们需要能够实时感知我们所运维的系统和服务的情况&#xff0c;比如以下的场景&#xff1a; 系统上线前测试&#xff1a;包括功能完整性检查&#xff0c;确保页面元素&#xff08;如图像、视频、脚本等&#xff09;都能够正常…...

Chrome离线安装包下载

1、问Chrome的官网&#xff1a;https://www.google.cn/chrome/ 直接下载的是在线安装包&#xff0c;安装需要联网。 2、如果需要在无法联网的设备上安装Chrome&#xff0c;需要在上面的地址后面加上?standalone1。 Chrome离线安装包下载地址&#xff1a;https://www.google.c…...