python找出仙剑二地图遮挡层图片在大地图中的坐标

使用方法:

把脚本放在图片目录下,输入图片编号即可(请手动删除全黑图块)

import os
import random

import cv2
import pygame


def get_small_images(dir_path, map_id):
    """
    获取小图文件
    """
    files = []
    for file_name in os.listdir(dir_path):
        if file_name.split('.')[-1] != 'bmp':
            continue

        n = file_name[:-4].split('-')
        if len(n) != 2:
            continue

        if n[0] != str(map_id):
            continue

        if n[1] == '1':
            continue
        files.append(dir_path + file_name)

    return files


def color_eq(rgb1, rgb2):
    return abs(rgb1[0] - rgb2[0]) < 10 and abs(rgb1[1] - rgb2[1]) < 10 and abs(rgb1[2] - rgb2[2]) < 10


def get_rgb(img, x, y):
    return [int(img[y, x, 2]), int(img[y, x, 1]), int(img[y, x, 0])]


def find_small_point(big_img, small_img):
    """
    找图思路:
        1.在小图中随机取n个特征点(特征点不为黑色)
        2.遍历大图所有像素点
        3.以当前遍历大图的像素点为左上角,选取小图大小的一块矩形区域
        4.将特征点与矩形区域相应位置的点进行对比
        5.特征点全部比对上,成功找出小图位置
    """
    # 1.选取特征点
    n = 20
    count = 0
    feature_point = []
    while 1:
        x = random.randint(0, small_img.shape[1] - 1)
        y = random.randint(0, small_img.shape[0] - 1)
        rgb = get_rgb(small_img, x, y)

        if rgb[0] == 0 and rgb[1] == 0 and rgb[2] == 0:
            continue

        count += 1
        feature_point.append({'x': x, 'y': y, 'rgb': rgb})

        if count == n:
            break

    # 2.遍历大图所有像素点
    for y in range(big_img.shape[0] - small_img.shape[0]+1):
        for x in range(big_img.shape[1] - small_img.shape[1]+1):
            check_count = 0
            for point in feature_point:
                rgb1 = get_rgb(big_img, x + point['x'], y + point['y'])
                if color_eq(rgb1, point['rgb']):
                    check_count += 1
                    continue
                else:
                    break
            if check_count == n:
                return [x, y]  # 找到了

    return None  # 没找到


def main():
    # 初始化pygame
    pygame.init()
    pygame.display.set_mode((1, 1))
    mapid = int(input("请输入map_id:"))
    path = r"./"
    map_img = cv2.imread(path + str(mapid) + "-1.bmp")
    small_path = get_small_images(path, mapid)
    # 创建透明surface
    surface_buffer = pygame.Surface((map_img.shape[1], map_img.shape[0]), flags=pygame.SRCALPHA)
    pygame.Surface.convert(surface_buffer)
    surface_buffer.fill(pygame.Color(255, 255, 255, 0))

    for small in small_path:
        small_img = cv2.imread(small)
        point = find_small_point(map_img, small_img)
        if point is not None:
            # 创建图片
            small_surface = pygame.image.load(small)
            small_surface.set_colorkey((0, 0, 0))
            surface_buffer.blit(small_surface, point)

        print("图片:", small, " 坐标:", point)
    # 保存图片
    pygame.image.save(surface_buffer, path + str(mapid) + ".png")


if __name__ == '__main__':
    main()

 

另一个脚本,导出每个遮挡图片在大图中的坐标(以左下角为原点):

import json
import os
import random

import cv2
import pygame


def get_small_images(dir_path, map_id):
    """
    获取小图文件
    """
    files = []
    for file_name in os.listdir(dir_path):
        if file_name.split('.')[-1] != 'bmp':
            continue

        n = file_name[:-4].split('-')
        if len(n) != 2:
            continue

        if n[0] != str(map_id):
            continue

        if n[1] == '1':
            continue
        files.append(dir_path + file_name)

    return files


def color_eq(rgb1, rgb2):
    return abs(rgb1[0] - rgb2[0]) < 10 and abs(rgb1[1] - rgb2[1]) < 10 and abs(rgb1[2] - rgb2[2]) < 10


def get_rgb(img, x, y):
    return [int(img[y, x, 2]), int(img[y, x, 1]), int(img[y, x, 0])]


def find_small_point(big_img, small_img):
    """
    找图思路:
        1.在小图中随机取n个特征点(特征点不为黑色)
        2.遍历大图所有像素点
        3.以当前遍历大图的像素点为左上角,选取小图大小的一块矩形区域
        4.将特征点与矩形区域相应位置的点进行对比
        5.特征点全部比对上,成功找出小图位置
    """
    # 1.选取特征点
    n = 20
    count = 0
    feature_point = []
    while 1:
        x = random.randint(0, small_img.shape[1] - 1)
        y = random.randint(0, small_img.shape[0] - 1)
        rgb = get_rgb(small_img, x, y)

        if rgb[0] == 0 and rgb[1] == 0 and rgb[2] == 0:
            continue

        count += 1
        feature_point.append({'x': x, 'y': y, 'rgb': rgb})

        if count == n:
            break

    # 2.遍历大图所有像素点
    for y in range(big_img.shape[0] - small_img.shape[0] + 1):
        for x in range(big_img.shape[1] - small_img.shape[1] + 1):
            check_count = 0
            for point in feature_point:
                rgb1 = get_rgb(big_img, x + point['x'], y + point['y'])
                if color_eq(rgb1, point['rgb']):
                    check_count += 1
                    continue
                else:
                    break
            if check_count == n:
                return [x, big_img.shape[0] - y - small_img.shape[0]]  # 找到了

    return None  # 没找到


def main():
    # 初始化pygame
    pygame.init()
    pygame.display.set_mode((1, 1))
    mapid = int(input("请输入map_id:"))
    path = r"./"
    map_img = cv2.imread(path + str(mapid) + "-1.bmp")
    small_path = get_small_images(path, mapid)
    # 创建透明surface
    surface_buffer = pygame.Surface((map_img.shape[1], map_img.shape[0]), flags=pygame.SRCALPHA)
    pygame.Surface.convert(surface_buffer)
    surface_buffer.fill(pygame.Color(255, 255, 255, 0))

    data = {
        "data": []
    }
    for small in small_path:
        small_img = cv2.imread(small)
        point = find_small_point(map_img, small_img)
        if point is not None:
            # 创建图片
            small_surface = pygame.image.load(small)
            small_surface.set_colorkey((0, 0, 0))
            surface_buffer.blit(small_surface, point)
            data["data"].append({
                "path": small[2:].split(".")[0],
                "x": point[0],
                "y": point[1]
            })
        else:
            print(f"找图失败:{small}")
        print("图片:", small, " 坐标:", point)

    # 保存图片
    pygame.image.save(surface_buffer, path + str(mapid) + ".png")
    with open(f"./{mapid}.json", mode="w") as file:
        file.write(json.dumps(data))


if __name__ == '__main__':
    main()

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值