From 6fc2a0431f0eb237126cbb5777fc0af2904f8e8e Mon Sep 17 00:00:00 2001 From: fuyn101 Date: Thu, 30 Jan 2025 14:12:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B0=B4=E5=B9=B3=E6=8B=BC=E6=8E=A5orb=20flann?= =?UTF-8?q?=20=E8=87=AA=E5=8A=A8=E8=AF=86=E5=88=AB=E9=87=8D=E5=8F=A0?= =?UTF-8?q?=E5=8C=BA=E5=9F=9F=20=E6=97=A0=E6=8E=A5=E7=BC=9D=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20=E6=A3=AE=E7=A9=BA=E5=B2=9B=E5=9F=BA=E6=9C=AC?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=EF=BC=88=E7=BB=83=E5=BA=A6=E8=AF=BB=E5=8F=96?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 森空岛获取基本信息.py | 49 ++++++ ...拼接orb flann 自动识别重叠区域 无接缝修复.py | 142 ++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 森空岛获取基本信息.py create mode 100644 水平拼接orb flann 自动识别重叠区域 无接缝修复.py diff --git a/森空岛获取基本信息.py b/森空岛获取基本信息.py new file mode 100644 index 00000000..abbb67a5 --- /dev/null +++ b/森空岛获取基本信息.py @@ -0,0 +1,49 @@ +import json + +import requests + +from mower.utils import config +from mower.utils.path import get_path +from mower.utils.skland import ( + get_binding_list, + get_cred_by_token, + get_sign_header, + header, + log, +) + + +class cultivate: + solver_name = "森空岛数据获取" + + def __init__(self): + self.record_path = get_path("@app/tmp/cultivate.json") + self.reward = [] + self.sign_token = "" + self.all_recorded = True + + def start(self): + item = config.conf.skland_info[0] + if item.isCheck: + a = get_cred_by_token(log(item)) + self.save_param(a) + print(a) + for i in get_binding_list(self.sign_token): + body = {"gameId": 1, "uid": i.get("uid")} + ingame = f"https://zonai.skland.com/api/v1/game/player/info?uid={i.get('uid')}" + resp = requests.get( + ingame, + headers=get_sign_header(ingame, "get", body, self.sign_token), + timeout=5, + ).json() + print(resp) + with open(self.record_path, "w", encoding="utf-8") as file: + json.dump(resp, file, ensure_ascii=False, indent=4) + + def save_param(self, cred_resp): + header["cred"] = cred_resp["cred"] + self.sign_token = cred_resp["token"] + + +a = cultivate() +a.start() diff --git a/水平拼接orb flann 自动识别重叠区域 无接缝修复.py b/水平拼接orb flann 自动识别重叠区域 无接缝修复.py new file mode 100644 index 00000000..a9f231fd --- /dev/null +++ b/水平拼接orb flann 自动识别重叠区域 无接缝修复.py @@ -0,0 +1,142 @@ +import cv2 +import numpy as np +from glob import glob + + +class ImageStitcher: + def __init__(self, folder_path=None): + self.images = [] # 存储图像的列表 + self.offsets = [] # 存储每对图像的偏移量 + if folder_path: + self.load_images(folder_path) # 如果提供了文件夹路径,则加载图像 + + def load_images(self, folder_path): + """加载指定文件夹中的所有PNG图像,并裁剪掉顶部300像素。""" + self.images = [] + for item in glob(f"{folder_path}/*.png"): + img = cv2.imread(item)[300:] + if img is not None: + self.images.append(img) # 裁剪掉顶部300像素 + else: + print(f"Warning: Unable to load image {item}") + + def calculate_offsets(self): + """计算每对相邻图像的偏移量。""" + if len(self.images) < 2: + raise ValueError("At least two images are required to calculate offsets.") + + # 初始化 ORB 检测器 + orb = cv2.ORB_create() + + # 初始化 FLANN 匹配器(针对二进制描述符) + FLANN_INDEX_LSH = 6 # LSH 算法适用于二进制描述符 + index_params = dict( + algorithm=FLANN_INDEX_LSH, + table_number=6, # 哈希表数量 + key_size=12, # 哈希键大小 + multi_probe_level=1, # 多探针级别 + ) + search_params = dict(checks=20) # 控制搜索精度,值越大越精确但越慢 + flann = cv2.FlannBasedMatcher(index_params, search_params) + + # 预计算所有图像的关键点和描述符 + keypoints_and_descriptors = [] + for img in self.images: + keypoints, descriptors = orb.detectAndCompute(img, None) + keypoints_and_descriptors.append((keypoints, descriptors)) + + self.offsets = [] # 清空偏移量 + for i in range(len(self.images) - 1): + keypoints1, descriptors1 = keypoints_and_descriptors[i] + keypoints2, descriptors2 = keypoints_and_descriptors[i + 1] + + # 使用 FLANN 进行特征匹配 + matches = flann.knnMatch(descriptors1, descriptors2, k=2) + + # 过滤匹配点,使用 Lowe's ratio test + good_matches = [] + for match_pair in matches: + if len(match_pair) == 2: # 确保每个匹配对有两个点 + m, n = match_pair + if m.distance < 0.8 * n.distance: # Lowe's ratio test + good_matches.append(m) + + # 至少需要 4 个匹配点来计算单应性矩阵 + if len(good_matches) >= 4: + src_pts = np.float32( + [keypoints1[m.queryIdx].pt for m in good_matches] + ).reshape(-1, 1, 2) + dst_pts = np.float32( + [keypoints2[m.trainIdx].pt for m in good_matches] + ).reshape(-1, 1, 2) + + # 计算单应性矩阵 + H, _ = cv2.findHomography(dst_pts, src_pts, cv2.RANSAC, 5.0) + + # 计算 curr_img 的四个角在 prev_img 坐标系中的位置 + h, w = self.images[i + 1].shape[:2] + corners = np.float32( + [[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]] + ).reshape(-1, 1, 2) + warped_corners = cv2.perspectiveTransform(corners, H) + + # 计算偏移量 + offset_x = int(warped_corners[0][0][0]) # 左上角的 x 坐标 + offset_y = int(warped_corners[0][0][1]) # 左上角的 y 坐标 + self.offsets.append((offset_x, offset_y)) + else: + raise ValueError( + f"Not enough matches found between image {i} and image {i + 1}." + ) + + def stitch_images(self): + """根据偏移量统一拼接所有图像。""" + if not self.images: + raise ValueError("No images provided for stitching.") + if not self.offsets: + self.calculate_offsets() # 如果没有计算偏移量,则先计算 + + # 计算每张图像在最终拼接图像中的绝对位置 + absolute_positions = [(0, 0)] # 第一张图像的绝对位置为 (0, 0) + for i in range(1, len(self.images)): + prev_x, prev_y = absolute_positions[i - 1] + offset_x, offset_y = self.offsets[i - 1] + absolute_positions.append((prev_x + offset_x, prev_y + offset_y)) + + # 计算最终拼接图像的大小 + min_x = min(pos[0] for pos in absolute_positions) + min_y = min(pos[1] for pos in absolute_positions) + max_x = max( + pos[0] + img.shape[1] for pos, img in zip(absolute_positions, self.images) + ) + max_y = max( + pos[1] + img.shape[0] for pos, img in zip(absolute_positions, self.images) + ) + + # 创建空白图像用于存储拼接结果 + stitched_image = np.zeros((max_y - min_y, max_x - min_x, 3), dtype=np.uint8) + + # 将每张图像放置到正确的位置 + for img, (x, y) in zip(self.images, absolute_positions): + x -= min_x + y -= min_y + stitched_image[y : y + img.shape[0], x : x + img.shape[1]] = img + + return stitched_image + + +def main(): + folder_path = "./img" # 图像文件夹路径 + + # 创建 ImageStitcher 实例并加载图像 + stitcher = ImageStitcher(folder_path) + + # 拼接图像 + stitched_image = stitcher.stitch_images() + + # 保存结果 + cv2.imwrite("result.png", stitched_image) + + +if __name__ == "__main__": + main()