python中使用DNF Extractor和PIL定位dnf中物品位置

 

基本实现思路是使用DNF Extractor将物品的贴图添加上特定颜色的像素块,然后再在截图中寻找特点的像素定位物品位置。

我们以数据芯片为例

dnf python脚本 python脚本dnf捡物品跑图_dnf python脚本

DNF Extractor替换贴图

断网安装DNF Extractor 然后防火墙禁用网络连接。

dnf python脚本 python脚本dnf捡物品跑图_dnf python脚本_02

打开npk文件,dnf安装路径下ImagePacks2文件夹,sprite_item.NPK。如图所示数据芯片的贴图是在fielf_material.img下面的第97个。

dnf python脚本 python脚本dnf捡物品跑图_dnf python脚本_03

我们右键提取贴图。然后使用ps在提取的图片上放置一个色块(RGB:255,237,99)

dnf python脚本 python脚本dnf捡物品跑图_Image_04

。最后右键替换贴图,替换贴图前可以将nkp文件备份一份。

dnf python脚本 python脚本dnf捡物品跑图_Image_05

定位物品位置

进入游戏我们发现掉落物品的贴图已经被替换了。

sp1.jpg:

dnf python脚本 python脚本dnf捡物品跑图_Image_06

使用像素RGB定位物品位置

from PIL import Image

# 打开要处理的图像
img_src = Image.open('sp1.jpg')

# 转换图片的模式为RGB
img = img_src.convert('RGB')

r, g, b = 255, 237, 99

pixs = []

# 遍历图片获取指定像素的点
for x in range(img.size[0]):
    for y in range(img.size[1]):
        pix = img.getpixel((x, y))
        if (pix[0] == r) and (g - 3 <= pix[1] <= g + 3) and (b - 3 <= pix[2] <= b + 3):
            pixs.append([x, y])

new_img = Image.new("RGB", img.size)

pixTuple = (r, g, b)

# 新建图片在图片上画点
for i in pixs:
    new_img.putpixel((i[0], i[1]), pixTuple)
new_img.save("new_sp1.png")

new_sp1.jpg:

dnf python脚本 python脚本dnf捡物品跑图_dnf python脚本_07

去除噪点

使用九宫格法去除噪点。判断当前像素周围一圈的像素色值是否与当前的相同,当周围一圈八个像素至少有七个相同时,我们就认为当前像素不是噪点。

如下图所示的中间像素即为噪点。

dnf python脚本 python脚本dnf捡物品跑图_Image_08

from PIL import Image

# 打开要处理的图像
img_src = Image.open('sp1.jpg')

# 转换图片的模式为RGB
img = img_src.convert('RGB')

def checkPixel(r,g,b,pix):
    if (pix[0] == r) and (g - 3 <= pix[1] <= g + 3) and (b - 3 <= pix[2] <= b + 3):
        return True
    else:
        return False

r, g, b = 255, 237, 99

pixels = []

# 遍历图片获取指定像素的点
for x in range(img.size[0]):
    for y in range(img.size[1]):
        pix = img.getpixel((x, y))
        if checkPixel(r,g,b,pix):
            pix_set = []
            for m in range( x - 1, x + 2):
                for n in range( y - 1, y + 2):
                    _pix = img.getpixel((m, n))
                    if checkPixel(r,g,b,_pix):
                        pix_set.append(_pix)
            # 当九宫格中其他8格都匹配获取像素
            if len(pix_set) >= 7:
                pixels.append([x, y])
new_img = Image.new("RGB", img.size)

pixTuple = (r, g, b)

# 新建图片在图片上画点
for i in pixels:
    new_img.putpixel((i[0], i[1]), pixTuple)
new_img.save("new_sp1.png")

dnf python脚本 python脚本dnf捡物品跑图_dnf python脚本_09

可以发现绝大部分噪点已经清除了。

多个物品

在使用的过程中发现色块的像素过多,当检测一个物品时只需要在目标色值像素数组pixels中合理的选择一个当做当前物品的位置即可。当检测多个物品时,我们在pixels数组中无法直接知道物品的个数和位置信息。所以我们选择使用较少色块的像素,使用3x3色块。当使用九宫格筛选的时候刚好可以筛选出一个像素。

当时在使用过程中,我们发现会出现一些干扰点。dnf游戏画面中会存在一些色值和目标相同的像素,所以为了尽量避免干扰,我们在3x3色块外再加一圈特定的其让色值的辅助像素(为了更准确一点可以多加几圈)。将色块变成5x5。在原来九宫格判断的基础上再判断外面一层的色块是不是指定的色值。

dnf python脚本 python脚本dnf捡物品跑图_九宫格_10

测试多个物品

dnf python脚本 python脚本dnf捡物品跑图_Image_11

dnf python脚本 python脚本dnf捡物品跑图_贴图_12

#[[520, 308], [671, 430]] 两个像素的位置信息,对应着两个数据芯片
print(pixels)

 

 




基本实现思路是使用DNF Extractor将物品的贴图添加上特定颜色的像素块,然后再在截图中寻找特点的像素定位物品位置。

我们以数据芯片为例

dnf python脚本 python脚本dnf捡物品跑图_dnf python脚本

DNF Extractor替换贴图

断网安装DNF Extractor 然后防火墙禁用网络连接。

dnf python脚本 python脚本dnf捡物品跑图_dnf python脚本_02

打开npk文件,dnf安装路径下ImagePacks2文件夹,sprite_item.NPK。如图所示数据芯片的贴图是在fielf_material.img下面的第97个。

dnf python脚本 python脚本dnf捡物品跑图_dnf python脚本_03

我们右键提取贴图。然后使用ps在提取的图片上放置一个色块(RGB:255,237,99)

dnf python脚本 python脚本dnf捡物品跑图_Image_04

。最后右键替换贴图,替换贴图前可以将nkp文件备份一份。

dnf python脚本 python脚本dnf捡物品跑图_Image_05

定位物品位置

进入游戏我们发现掉落物品的贴图已经被替换了。

sp1.jpg:

dnf python脚本 python脚本dnf捡物品跑图_Image_06

使用像素RGB定位物品位置

from PIL import Image

# 打开要处理的图像
img_src = Image.open('sp1.jpg')

# 转换图片的模式为RGB
img = img_src.convert('RGB')

r, g, b = 255, 237, 99

pixs = []

# 遍历图片获取指定像素的点
for x in range(img.size[0]):
    for y in range(img.size[1]):
        pix = img.getpixel((x, y))
        if (pix[0] == r) and (g - 3 <= pix[1] <= g + 3) and (b - 3 <= pix[2] <= b + 3):
            pixs.append([x, y])

new_img = Image.new("RGB", img.size)

pixTuple = (r, g, b)

# 新建图片在图片上画点
for i in pixs:
    new_img.putpixel((i[0], i[1]), pixTuple)
new_img.save("new_sp1.png")

new_sp1.jpg:

dnf python脚本 python脚本dnf捡物品跑图_dnf python脚本_07

去除噪点

使用九宫格法去除噪点。判断当前像素周围一圈的像素色值是否与当前的相同,当周围一圈八个像素至少有七个相同时,我们就认为当前像素不是噪点。

如下图所示的中间像素即为噪点。

dnf python脚本 python脚本dnf捡物品跑图_Image_08

from PIL import Image

# 打开要处理的图像
img_src = Image.open('sp1.jpg')

# 转换图片的模式为RGB
img = img_src.convert('RGB')

def checkPixel(r,g,b,pix):
    if (pix[0] == r) and (g - 3 <= pix[1] <= g + 3) and (b - 3 <= pix[2] <= b + 3):
        return True
    else:
        return False

r, g, b = 255, 237, 99

pixels = []

# 遍历图片获取指定像素的点
for x in range(img.size[0]):
    for y in range(img.size[1]):
        pix = img.getpixel((x, y))
        if checkPixel(r,g,b,pix):
            pix_set = []
            for m in range( x - 1, x + 2):
                for n in range( y - 1, y + 2):
                    _pix = img.getpixel((m, n))
                    if checkPixel(r,g,b,_pix):
                        pix_set.append(_pix)
            # 当九宫格中其他8格都匹配获取像素
            if len(pix_set) >= 7:
                pixels.append([x, y])
new_img = Image.new("RGB", img.size)

pixTuple = (r, g, b)

# 新建图片在图片上画点
for i in pixels:
    new_img.putpixel((i[0], i[1]), pixTuple)
new_img.save("new_sp1.png")

dnf python脚本 python脚本dnf捡物品跑图_dnf python脚本_09

可以发现绝大部分噪点已经清除了。

多个物品

在使用的过程中发现色块的像素过多,当检测一个物品时只需要在目标色值像素数组pixels中合理的选择一个当做当前物品的位置即可。当检测多个物品时,我们在pixels数组中无法直接知道物品的个数和位置信息。所以我们选择使用较少色块的像素,使用3x3色块。当使用九宫格筛选的时候刚好可以筛选出一个像素。

当时在使用过程中,我们发现会出现一些干扰点。dnf游戏画面中会存在一些色值和目标相同的像素,所以为了尽量避免干扰,我们在3x3色块外再加一圈特定的其让色值的辅助像素(为了更准确一点可以多加几圈)。将色块变成5x5。在原来九宫格判断的基础上再判断外面一层的色块是不是指定的色值。

dnf python脚本 python脚本dnf捡物品跑图_九宫格_10

测试多个物品

dnf python脚本 python脚本dnf捡物品跑图_Image_11

dnf python脚本 python脚本dnf捡物品跑图_贴图_12

#[[520, 308], [671, 430]] 两个像素的位置信息,对应着两个数据芯片
print(pixels)