AI玩游戏的一点尝试(3)—— 图片去重

19 阅读2分钟

前言

AI玩游戏的一点尝试(1)—— 架构设计与初步状态识别

AI玩游戏的一点尝试(2)—— 初探无监督学习与特征可视化

图片去重

由于数据采集的截图是每秒一次,一旦有事离开会采集太多相同的图片,光是玩了几盘就已经收集了4G的图片了,训练时长也逐渐增加,感觉有必要对重复的图片进行去重。

image.png

像素相似度比对

因为游戏的大多数画面是动态的,直接比对像素去重效果肯定不太好,想根据相似度判断后去重,无奈图片比对太耗性能,O(N^2)的复杂度完全跑不动4G的图片,因此改成了只和前一张比对:

def is_same_image(img1_path, img2_path, threshold=0.99):
    with Image.open(img1_path) as img1, Image.open(img2_path) as img2:
        if img1.size != img2.size:
            return False
        
        img1_array = np.array(img1)
        img2_array = np.array(img2)
        
        if img1_array.shape != img2_array.shape:
            return False
            
        diff = np.abs(img1_array.astype(np.float32) - img2_array.astype(np.float32))
        similarity = 1 - (np.sum(diff) / (diff.size * 255))
        return similarity >= threshold

哈希相似度比对

但是和前一张比对只能处理放着不动产生的重复画面,对于多次游玩截图的重复画面依然没有办法解决。查阅资料得知imagehash库的phash和dhash可以对图片生成hash后计算相似度距离,于是编写代码测试:

image_hashes = {}
for img_path in tqdm(image_files, desc="计算图片哈希值"):
    with Image.open(img_path) as img:
        # 使用 dhash 算法,它对图片细节更敏感
        hash_value = imagehash.dhash(img)
        image_hashes[img_path] = str(hash_value)

查看比对结果发现,游戏的UI部分在画面占比较小,不同图片反映的信息不同,但是phash和dhash算法均不能很好的捕捉到UI数据的变化,把大量不同数据的图片归为了相似图片。

哈希去重

没办法还是直接通过像素计算哈希去重吧:

hash_cache = {}
for img_path in tqdm(image_files, desc="计算图片哈希值"):
    with Image.open(img_path) as img:
        img_array = np.array(img)
        hash_cache[img_path] = hashlib.sha256(img_array.tobytes()).hexdigest()

def is_same_image(img1_path, img2_path):
    hash1 = hash_cache[img1_path]
    hash2 = hash_cache[img2_path]
    
    return hash1 == hash2

和预想的一样,相似的图片很少,但是这个脚本对于后续数字识别的去重很有帮助。

下一步

现在已经有了准确的状态识别模型,那么就可以在养成界面截取数据进行数字识别了。