You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Win32API截图后OpenCV模板匹配报错求助

解决OpenCV模板匹配报错:templ is not a numpy array neither a scalar

核心错误原因

报错直接指出templ不是numpy数组或标量——你代码里的target是字符串'box.png',但cv.matchTemplate要求第二个参数必须是加载后的OpenCV图像(numpy数组),而不是文件路径字符串。

分步修复方案

  1. 提前加载目标模板图像
    在循环开始前用cv.imread()加载模板,避免每次循环重复读取文件:

    target = cv.imread('box.png')
    # 检查模板是否加载成功
    if target is None:
        raise FileNotFoundError("无法加载box.png,请检查文件路径是否正确")
    
  2. 统一图像通道格式
    你的windowcapture函数返回的是RGBA四通道图像(shape=(h,w,4)),而cv.imread默认加载的是BGR三通道图像,两者通道数不匹配会导致模板匹配失败。需要将截图转换为BGR格式:

    screenshot = windowcapture()
    # 转换RGBA到BGR
    screenshot_bgr = cv.cvtColor(screenshot, cv.COLOR_RGBA2BGR)
    
  3. 替换过时的numpy API
    np.fromstring已被弃用,改用np.frombuffer保证兼容性:

    # 原代码
    # img = np.fromstring(signedIntsArray, dtype='uint8')
    # 修改为
    img = np.frombuffer(signedIntsArray, dtype='uint8')
    

修改后的完整代码

import cv2 as cv
import numpy as np
from time import time
import win32gui, win32ui, win32con

game = 'LOST ARK (64-bit, DX9) v.2.5.3.1'
# 提前加载模板图像
target = cv.imread('box.png')
if target is None:
    raise FileNotFoundError("无法找到box.png,请确认文件路径正确")

def list_window_names():
    def winEnumHandler(hwnd, ctx):
        if win32gui.IsWindowVisible(hwnd):
            print(hex(hwnd), win32gui.GetWindowText(hwnd))
    win32gui.EnumWindows(winEnumHandler, None)

def windowcapture():
    hwnd = win32gui.FindWindow(None, game)
    if hwnd == 0:
        raise ValueError(f"未找到窗口:{game},请检查窗口标题是否正确")
    rect = win32gui.GetWindowRect(hwnd)
    w = rect[2] - rect[0]
    h = rect[3] - rect[1]
    wDc = win32gui.GetWindowDC(hwnd)
    dcObj = win32ui.CreateDCFromHandle(wDc)
    cDC = dcObj.CreateCompatibleDC()
    dataBitMap = win32ui.CreateBitmap()
    dataBitMap.CreateCompatibleBitmap(dcObj, w, h)
    cDC.SelectObject(dataBitMap)
    cDC.BitBlt((0, 0), (w, h), dcObj, (0, 0), win32con.SRCCOPY)

    signedIntsArray = dataBitMap.GetBitmapBits(True)
    # 替换fromstring为frombuffer
    img = np.frombuffer(signedIntsArray, dtype='uint8')
    img.shape = (h, w, 4)

    dcObj.DeleteDC()
    cDC.DeleteDC()
    win32gui.ReleaseDC(hwnd, wDc)
    win32gui.DeleteObject(dataBitMap.GetHandle())

    return img

list_window_names()
loop_time = time()
while True:
    screenshot = windowcapture()
    # 转换RGBA到BGR,和模板通道一致
    screenshot_bgr = cv.cvtColor(screenshot, cv.COLOR_RGBA2BGR)
    cv.imshow("computer vision", screenshot_bgr)
    
    method = cv.TM_CCORR_NORMED  # 推荐使用归一化的匹配方法,结果更稳定
    result = cv.matchTemplate(screenshot_bgr, target, method)

    print('FPS {}'.format(1 / (time() - loop_time)))
    loop_time = time()
    if cv.waitKey(1) == ord('q'):
        cv.destroyAllWindows()
        break

print('Done.')

额外注意事项

  • 确认game变量的窗口标题和实际游戏窗口标题完全一致(可以通过list_window_names()输出的结果核对),如果标题有误,FindWindow会返回0,导致截图失败。
  • 如果后续遇到游戏窗口黑屏问题,可能是游戏使用了硬件加速渲染,此时Win32API截图无法捕获画面,可以尝试使用专门针对游戏的截图库。

内容的提问来源于stack exchange,提问作者lycandown

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 17:54:32