本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:易语言是一种以中文语法为基础的编程语言,降低了编程门槛,适合初学者快速上手。本项目围绕“易语言找图”展开,利用位图操作支持库实现图像处理与识别功能,涵盖图像读取、模板匹配、像素比较、坐标定位等关键技术。适用于自动化测试、游戏辅助等场景,通过完整源码讲解帮助开发者掌握图像识别的实现流程与优化技巧。
易语言-易语言找图

1. 易语言简介与开发环境搭建

易语言是一款专为中文用户设计的可视化编程语言,其语法简洁直观,适合快速开发小型应用程序和自动化脚本。本章将从易语言的基本概念入手,逐步引导读者完成开发环境的搭建。

1.1 易语言概述

易语言由吴涛开发,旨在降低编程门槛,使非专业程序员也能轻松上手。其核心特点包括:
- 中文关键词 :所有语法结构使用中文,降低理解难度;
- 可视化界面设计 :支持拖拽控件,简化GUI开发;
- 丰富的内置函数库 :涵盖文件操作、网络通信、图形处理等多个领域。

例如,一个简单的“Hello World”程序如下:

.版本 2

.程序集 窗口程序集_启动窗口
.子程序 _按钮_显示_被单击

信息框 (“你好,世界!”, 0, , )

上述代码实现了点击按钮后弹出提示框的功能。其中:
- .版本 2 表示使用的是易语言的第二版语法;
- .程序集 定义了程序的逻辑结构;
- .子程序 表示事件处理函数;
- 信息框 是一个内置函数,用于弹出消息框。

易语言的这些特性使其在小型工具开发、自动化脚本、游戏外挂等领域广泛应用。

1.2 开发环境搭建

要开始使用易语言进行开发,首先需要搭建开发环境。

步骤一:下载安装包

前往易语言官网或可信的第三方站点下载最新版本的安装包(如 eBasicSetup.exe )。

步骤二:安装开发环境

运行安装包后,按照提示选择安装路径,推荐保持默认配置,确保所有组件都被选中。

安装完成后,打开易语言开发环境,界面如下:

  • 左侧资源管理器 :用于管理窗体、模块、类等资源;
  • 中间代码编辑区 :用于编写程序逻辑;
  • 右侧属性面板 :设置控件属性;
  • 底部工具箱 :包含各种可用控件。

步骤三:创建第一个项目

  1. 点击“新建” → “Windows应用程序”;
  2. 拖入一个“按钮”控件到主窗口;
  3. 双击按钮,进入事件处理函数;
  4. 输入代码如上所述;
  5. 点击“运行”按钮(或按下 F5)执行程序。

通过以上步骤,即可完成一个简单的易语言程序开发流程。

小结

本章介绍了易语言的基本概念及其开发环境的搭建流程。通过一个简单的“Hello World”程序,展示了易语言的编程风格与逻辑结构。下一章将深入讲解图像处理的核心支持库——位图操作库的使用方法,为后续图像查找功能的实现奠定基础。

2. 位图操作支持库使用方法

位图操作是图形处理中的核心环节,尤其在图像识别、查找、匹配等应用场景中,位图操作支持库的使用至关重要。本章将深入讲解易语言中位图操作支持库的使用方法,包括库的引入与配置、图像资源的加载与释放、图像绘制与显示,以及图像格式的转换与处理。通过本章的学习,读者将能够掌握位图操作的基本流程,为后续图像识别功能的实现打下坚实基础。

2.1 位图操作库概述

2.1.1 支持库的引入与配置

在易语言开发中,位图操作通常依赖于外部支持库。最常用的支持库包括“位图操作支持库”和“图形处理库”。这些库提供了丰富的函数接口,用于图像加载、绘制、格式转换等操作。

步骤一:下载支持库

首先,开发者需要从官方或可信资源下载支持库文件,例如 BitmapEx.ec GdiPlus.ec 。这些文件通常包含函数定义和资源声明。

步骤二:导入支持库

打开易语言开发环境,点击菜单栏“程序” > “导入支持库”,选择下载的 .ec 文件进行导入。

.版本 2
.支持库 eGdiPlus

.程序集 窗口程序集_启动窗口

代码说明:

  • .支持库 eGdiPlus 表示引入了 GDI+ 图形处理支持库。
  • 该库封装了 Windows GDI+ API,提供了更高级别的图像操作接口。

参数说明:

  • eGdiPlus :是 GDI+ 支持库的名称,包含了图像加载、绘图、格式转换等功能。

注意事项:

  • 在导入库时,确保所选库版本与当前易语言 IDE 兼容。
  • 若库中包含资源文件(如图标、位图),还需将其放置在项目资源目录中。

2.1.2 常用函数分类与功能说明

位图操作库通常提供以下几类常用函数:

函数分类 常用函数名称 功能说明
图像加载 载入图片 从文件或资源中加载图像
图像释放 释放图片 释放图像资源,防止内存泄漏
图像绘制 绘制图片 将图像绘制到指定设备上下文(如窗口、画板)
图像信息获取 取图片宽度 , 取图片高度 获取图像的尺寸信息
图像格式转换 图片转位图 , 位图转图片 实现图像格式之间的转换

示例代码:加载并显示图片

.版本 2

.程序集 窗口程序集_启动窗口
.子程序 _按钮_加载图片_被单击

.局部变量 图片句柄, 整数型

图片句柄 = 载入图片 (取运行目录 () + “\test.png”)
.如果真 (图片句柄 ≠ 0)
    绘制图片 (取窗口句柄 (), 图片句柄, 0, 0)
    释放图片 (图片句柄)
.如果真结束

代码逻辑分析:

  • 载入图片 函数从指定路径加载图片文件,返回图片句柄。
  • 绘制图片 函数将图片绘制到窗口,参数分别为窗口句柄、图片句柄、X坐标、Y坐标。
  • 释放图片 避免内存泄漏,及时释放资源。

参数说明:

  • 取运行目录() :获取当前程序运行目录。
  • 取窗口句柄() :获取当前窗口的设备上下文句柄。

2.2 图像资源的加载与释放

2.2.1 加载位图文件到内存

加载位图文件是图像处理的第一步。在易语言中,加载位图通常使用 载入图片 载入位图 函数。

代码示例:

.版本 2

.程序集 窗口程序集_启动窗口
.子程序 _按钮_加载位图_被单击

.局部变量 位图句柄, 整数型

位图句柄 = 载入位图 (取运行目录 () + “\icon.bmp”)
.如果真 (位图句柄 ≠ 0)
    信息框 (“位图加载成功!”, 0, , )
.否则
    信息框 (“位图加载失败!”, 0, , )
.如果真结束

流程图:

graph TD
A[开始] --> B[调用载入位图函数]
B --> C{是否加载成功?}
C -->|是| D[显示成功提示]
C -->|否| E[显示失败提示]

代码分析:

  • 载入位图 返回值为位图句柄,若返回 0 表示加载失败。
  • 使用 信息框 提示用户加载状态,增强交互性。

参数说明:

  • 取运行目录() :获取当前程序运行目录。
  • 载入位图 函数接受一个字符串参数,表示位图文件路径。

2.2.2 释放位图资源防止内存泄漏

位图资源加载后若未及时释放,将导致内存占用持续增长,最终可能引发程序崩溃。因此,释放位图资源是图像处理中不可或缺的一环。

代码示例:

.版本 2

.程序集 窗口程序集_启动窗口
.子程序 _按钮_释放位图_被单击

.局部变量 位图句柄, 整数型

位图句柄 = 载入位图 (取运行目录 () + “\icon.bmp”)
.如果真 (位图句柄 ≠ 0)
    释放位图 (位图句柄)
    信息框 (“位图资源已释放!”, 0, , )
.如果真结束

表格:内存管理对比

操作 是否释放资源 内存占用情况
加载后未释放 持续增长
加载后及时释放 正常释放

代码逻辑分析:

  • 释放位图 函数接受一个位图句柄作为参数,释放对应内存。
  • 即使程序结束,也应显式释放资源,以避免资源未回收问题。

参数说明:

  • 位图句柄 :必须是有效的句柄,否则可能导致程序异常。

2.3 图像绘制与显示

2.3.1 图像绘制到窗口控件

图像绘制是将图像数据输出到可视化界面上的过程。易语言中可以使用 绘制图片 绘制位图 函数实现。

代码示例:

.版本 2

.程序集 窗口程序集_启动窗口
.子程序 _按钮_绘制图片_被单击

.局部变量 图片句柄, 整数型

图片句柄 = 载入图片 (取运行目录 () + “\background.jpg”)
.如果真 (图片句柄 ≠ 0)
    绘制图片 (取窗口句柄 (), 图片句柄, 10, 10)
    释放图片 (图片句柄)
.如果真结束

流程图:

graph TD
A[开始] --> B[加载图片]
B --> C[绘制图片]
C --> D[释放资源]

代码分析:

  • 绘制图片 函数将图片绘制到窗口指定坐标(10, 10)。
  • 绘制完成后调用 释放图片 ,确保资源回收。

参数说明:

  • 取窗口句柄() :获取当前窗口的设备上下文句柄。
  • 10, 10 :绘制图像的起始坐标。

2.3.2 图像缩放与裁剪技巧

图像在绘制时可能需要缩放或裁剪以适应窗口布局。易语言提供了 绘制图片_指定大小 函数,支持自定义绘制尺寸。

代码示例:

.版本 2

.程序集 窗口程序集_启动窗口
.子程序 _按钮_缩放图片_被单击

.局部变量 图片句柄, 整数型

图片句柄 = 载入图片 (取运行目录 () + “\photo.png”)
.如果真 (图片句柄 ≠ 0)
    绘制图片_指定大小 (取窗口句柄 (), 图片句柄, 50, 50, 200, 150)
    释放图片 (图片句柄)
.如果真结束

表格:绘制方式对比

函数名称 功能描述 是否支持缩放
绘制图片 按原始尺寸绘制
绘制图片_指定大小 指定绘制尺寸,支持缩放

代码分析:

  • 绘制图片_指定大小 的参数依次为:窗口句柄、图片句柄、X坐标、Y坐标、宽度、高度。
  • 该函数可用于实现图像缩放、裁剪等效果。

参数说明:

  • 200, 150 :指定绘制图像的宽度和高度。

2.4 图像格式转换与处理

2.4.1 位图数据的获取与操作

位图数据是图像处理的核心。在易语言中,可以使用 取图片数据 函数获取图像的原始数据,进行进一步处理。

代码示例:

.版本 2

.程序集 窗口程序集_启动窗口
.子程序 _按钮_获取位图数据_被单击

.局部变量 图片句柄, 整数型
.局部变量 数据, 字节集

图片句柄 = 载入图片 (取运行目录 () + “\image.png”)
.如果真 (图片句柄 ≠ 0)
    数据 = 取图片数据 (图片句柄)
    信息框 (“位图数据长度:” + 到文本 (取字节集长度 (数据)), 0, , )
    释放图片 (图片句柄)
.如果真结束

代码逻辑分析:

  • 取图片数据 函数返回图像的原始字节数据。
  • 通过 取字节集长度 获取数据长度,用于后续处理或分析。

参数说明:

  • 数据 :存储图像原始数据的字节集变量。

2.4.2 格式转换与兼容性处理

图像格式转换常用于解决不同图像格式间的兼容性问题。例如将 PNG 转换为 BMP,或将位图转换为 JPEG。

代码示例:

.版本 2

.程序集 窗口程序集_启动窗口
.子程序 _按钮_转换格式_被单击

.局部变量 图片句柄, 整数型

图片句柄 = 载入图片 (取运行目录 () + “\image.png”)
.如果真 (图片句柄 ≠ 0)
    保存图片 (图片句柄, 取运行目录 () + “\image.bmp”, #BMP格式)
    释放图片 (图片句柄)
    信息框 (“格式转换完成!”, 0, , )
.如果真结束

流程图:

graph TD
A[加载图片] --> B[转换格式]
B --> C[保存为新格式]
C --> D[释放资源]

代码分析:

  • 保存图片 函数可指定保存路径和格式(如 BMP、JPEG 等)。
  • 该功能可用于图像格式转换、备份等场景。

参数说明:

  • #BMP格式 :表示目标保存格式,为常量定义。

以上内容完整展示了第二章“位图操作支持库使用方法”的详细章节内容,涵盖图像加载、绘制、释放、格式转换等核心操作,并结合代码、流程图、表格等多种形式增强可读性和实用性。

3. 图像读取与加载实现

图像处理的基础是正确读取和加载图像文件。本章将深入探讨图像读取的底层实现机制,包括图像格式的解析、内存数据结构的设计、API调用方式以及性能优化策略。通过本章内容,读者将掌握如何在易语言环境中实现高效的图像加载流程,为后续的图像处理功能打下坚实基础。

3.1 图像文件格式解析

3.1.1 BMP、PNG等常见格式结构

图像文件格式是图像数据在磁盘上的存储方式,不同的格式具有不同的结构特点。常见的图像格式包括 BMP(位图)、PNG(可移植网络图形)和 JPEG(联合图像专家组)等。

  • BMP(Bitmap) :BMP 是一种无压缩或使用 RLE 压缩的图像格式,结构简单,便于解析。其基本结构包括文件头(BITMAPFILEHEADER)、信息头(BITMAPINFOHEADER)和像素数据。
  • PNG(Portable Network Graphics) :PNG 支持无损压缩,结构较为复杂,包含多个数据块(Chunk),每个数据块包含类型、长度、数据和CRC校验码。
  • JPEG(Joint Photographic Experts Group) :JPEG 采用有损压缩算法,适合存储照片类图像,解析较为复杂。

下表展示了三种常见图像格式的基本特性:

格式 压缩方式 是否支持透明 结构复杂度 适用场景
BMP 无压缩或 RLE 简单 图像处理教学、简单图形显示
PNG 无损压缩 是(支持 Alpha 通道) 中等 网页图像、图标、透明图层
JPEG 有损压缩 数码照片、图像压缩传输

3.1.2 文件头与图像数据提取

以 BMP 格式为例,其文件头包含以下关键结构:

  • BITMAPFILEHEADER (14字节):描述文件类型、大小、数据偏移量。
  • BITMAPINFOHEADER (40字节):描述图像宽度、高度、位数、压缩方式、图像大小等信息。
  • RGBQUAD (可选):调色板信息,用于 8 位以下图像。
  • 像素数据 :图像的原始数据,按行存储,每行字节数为 4 的整数倍。

以下是一个读取 BMP 文件头信息的易语言代码示例:

.版本 2

.程序集 窗口程序集_启动窗口
.子程序 _按钮_读取BMP_被单击

.局部变量 文件号, 整数型
.局部变量 文件头, BITMAPFILEHEADER
.局部变量 信息头, BITMAPINFOHEADER

文件号 = 打开文件 (“test.bmp”, #读入, )
读文件 (文件号, 到字节集 (文件头), 14)  ' 读取文件头
读文件 (文件号, 到字节集 (信息头), 40)  ' 读取信息头

调试输出 (“文件大小:”, 文件头.文件大小)
调试输出 (“图像宽度:”, 信息头.宽度)
调试输出 (“图像高度:”, 信息头.高度)
调试输出 (“位深度:”, 信息头.位数)

关闭文件 (文件号)

.结构体 BITMAPFILEHEADER
    .成员 类型, 整数型
    .成员 文件大小, 整数型
    .成员 保留, 整数型
    .成员 数据偏移, 整数型
.成员 结束

.结构体 BITMAPINFOHEADER
    .成员 结构大小, 整数型
    .成员 宽度, 整数型
    .成员 高度, 整数型
    .成员 平面数, 整数型
    .成员 位数, 整数型
    .成员 压缩方式, 整数型
    .成员 图像大小, 整数型
    .成员 水平分辨率, 整数型
    .成员 垂直分辨率, 整数型
    .成员 颜色索引数, 整数型
    .成员 重要颜色数, 整数型
.成员 结束

代码解析:

  • 使用 打开文件 函数打开 BMP 文件;
  • 使用 读文件 函数分别读取文件头(14 字节)和信息头(40 字节);
  • 将读取到的字节数据转换为结构体类型进行访问;
  • 输出图像的基本信息(大小、宽高、位数);
  • 最后关闭文件。

此代码演示了如何从 BMP 文件中提取文件头和图像信息头,为进一步读取像素数据打下基础。

3.2 图像内存数据结构设计

3.2.1 位图信息头解析

图像在内存中的表示方式通常由位图信息头(BITMAPINFO)和像素数据组成。BITMAPINFO 包含 BITMAPINFOHEADER 和调色板信息(可选)。

BITMAPINFOHEADER 包含以下关键字段:

  • biWidth :图像宽度(像素)
  • biHeight :图像高度(像素)
  • biPlanes :目标设备的平面数(通常为1)
  • biBitCount :每个像素的位数(如 1、4、8、16、24、32)
  • biCompression :压缩方式(BI_RGB、BI_RLE8、BI_RLE4、BI_BITFIELDS 等)
  • biSizeImage :图像数据大小(字节)
  • biXPelsPerMeter / biYPelsPerMeter :水平/垂直分辨率
  • biClrUsed :使用的颜色索引数
  • biClrImportant :重要颜色数

3.2.2 像素数据存储方式

像素数据在内存中的排列方式取决于图像的位深度:

  • 24位图像 :每个像素由 3 个字节表示(RGB),每行字节数为 3 × 宽度,需补齐为 4 的倍数;
  • 32位图像 :每个像素由 4 个字节表示(RGBA),每行 4 × 宽度;
  • 8位图像 :每个像素由 1 个字节表示,需配合调色板使用。

图像在内存中通常使用 BITMAPINFO 和像素数据指针组成,例如:

typedef struct tagBITMAPINFO {
    BITMAPINFOHEADER bmiHeader;
    RGBQUAD          bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;

在易语言中,可以通过结构体模拟该结构,并结合内存操作函数(如 分配内存 读内存 写内存 )实现图像数据的访问和操作。

3.3 图像读取功能实现

3.3.1 使用API函数读取图像

Windows 提供了 GDI(图形设备接口)API,可以用于图像的加载与显示。常用的函数包括:

  • LoadImageW :用于加载位图、图标或光标;
  • CreateDIBSection :创建设备无关位图(DIB);
  • GetDIBits :获取位图像素数据。

以下是一个使用 LoadImageW 加载图像并获取像素数据的示例:

.版本 2

.程序集 窗口程序集_启动窗口
.子程序 _按钮_加载图像_被单击

.局部变量 hBitmap, 整数型
.局部变量 bmi, BITMAPINFO
.局部变量 pBits, 整数型
.局部变量 hdc, 整数型
.局部变量 width, 整数型
.局部变量 height, 整数型

hBitmap = LoadImageW (0, “test.bmp”, #IMAGE_BITMAP, 0, 0, #LR_LOADFROMFILE)
hdc = GetDC (0)

' 初始化 BITMAPINFO
bmi.bmiHeader.结构大小 = 40
bmi.bmiHeader.宽度 = 0
bmi.bmiHeader.高度 = 0

' 获取位图信息
GetObjectA (hBitmap, 24, 取地址 (width))

' 填充 BITMAPINFO
bmi.bmiHeader.宽度 = width
bmi.bmiHeader.高度 = height

' 获取像素数据
pBits = 分配内存 (bmi.bmiHeader.图像大小)
GetDIBits (hdc, hBitmap, 0, height, pBits, 取地址 (bmi), #DIB_RGB_COLORS)

' 此时 pBits 指向像素数据,可进行处理

释放内存 (pBits)
ReleaseDC (0, hdc)
DeleteObject (hBitmap)

.结构体 BITMAPINFOHEADER
    .成员 结构大小, 整数型
    .成员 宽度, 整数型
    .成员 高度, 整数型
    .成员 平面数, 整数型
    .成员 位数, 整数型
    .成员 压缩方式, 整数型
    .成员 图像大小, 整数型
    .成员 水平分辨率, 整数型
    .成员 垂直分辨率, 整数型
    .成员 颜色索引数, 整数型
    .成员 重要颜色数, 整数型
.成员 结束

.结构体 BITMAPINFO
    .成员 bmiHeader, BITMAPINFOHEADER
    .成员 bmiColors, RGBQUAD
.成员 结束

.结构体 RGBQUAD
    .成员 rgbBlue, 字节型
    .成员 rgbGreen, 字节型
    .成员 rgbRed, 字节型
    .成员 rgbReserved, 字节型
.成员 结束

代码逻辑分析:

  • 使用 LoadImageW 加载 BMP 文件;
  • 使用 GetObjectA 获取位图的宽度和高度;
  • 初始化 BITMAPINFO 结构;
  • 使用 GetDIBits 获取像素数据到 pBits 指针;
  • 处理完成后释放内存资源。

3.3.2 自定义图像读取函数封装

为了提高代码复用性,可以将图像读取功能封装为一个函数,返回图像的宽度、高度和像素数据指针。

示例封装函数:

.版本 2

.程序集 窗口程序集_启动窗口
.子程序 图像读取, 逻辑型

.参数 文件路径, 文本型
.参数 宽度, 整数型, 参考
.参数 高度, 整数型, 参考
.参数 像素数据, 整数型, 参考

.局部变量 hBitmap, 整数型
.局部变量 hdc, 整数型
.局部变量 bmi, BITMAPINFO
.局部变量 pBits, 整数型

hBitmap = LoadImageW (0, 文件路径, #IMAGE_BITMAP, 0, 0, #LR_LOADFROMFILE)
.如果真 (hBitmap = 0)
    返回 (假)
.如果真结束

hdc = GetDC (0)
GetObjectA (hBitmap, 24, 取地址 (宽度))
GetObjectA (hBitmap, 24, 取地址 (高度))

bmi.bmiHeader.结构大小 = 40
bmi.bmiHeader.宽度 = 宽度
bmi.bmiHeader.高度 = 高度
bmi.bmiHeader.位数 = 24
bmi.bmiHeader.平面数 = 1
bmi.bmiHeader.压缩方式 = 0

pBits = 分配内存 (宽度 × 高度 × 3)
GetDIBits (hdc, hBitmap, 0, 高度, pBits, 取地址 (bmi), #DIB_RGB_COLORS)

像素数据 = pBits

返回 (真)

函数说明:

  • 接收文件路径、输出宽度、高度和像素数据指针;
  • 返回是否成功读取图像;
  • 内部封装了加载、解析和数据获取流程;
  • 调用者可直接使用像素数据进行后续处理。

3.4 图像加载性能优化

3.4.1 多线程图像加载策略

图像加载往往涉及磁盘 I/O 操作和内存处理,容易造成主线程阻塞。为了提升加载效率,可以采用多线程技术,将图像加载过程放在子线程中执行。

易语言中可以使用 创建线程 函数创建子线程,并在子线程中执行图像加载任务:

.版本 2

.程序集 窗口程序集_启动窗口
.子程序 _按钮_多线程加载_被单击

.局部变量 线程句柄, 整数型

线程句柄 = 创建线程 (&图像加载线程, “test.bmp”)
等待线程完成 (线程句柄)

.子程序 图像加载线程, 整数型

.参数 参数, 文本型

.局部变量 宽度, 整数型
.局部变量 高度, 整数型
.局部变量 像素数据, 整数型

.如果真 (图像读取 (参数, 宽度, 高度, 像素数据) = 真)
    调试输出 (“图像加载完成,尺寸:”, 宽度, “x”, 高度)
    释放内存 (像素数据)
.否则
    调试输出 (“图像加载失败”)
.如果真结束

返回 (0)

代码分析:

  • 使用 创建线程 启动子线程;
  • 子线程中调用 图像读取 函数加载图像;
  • 加载完成后释放内存;
  • 主线程通过 等待线程完成 等待子线程执行完毕。

该策略可显著提升图像加载效率,尤其在加载多个图像时效果更明显。

3.4.2 图像缓存机制设计

在频繁访问图像资源的场景下,可以设计图像缓存机制,将已加载的图像数据缓存到内存中,避免重复加载。

缓存机制可使用哈希表(或字典)来实现,以文件路径为键,图像数据为值:

.版本 2

.程序集 窗口程序集_启动窗口
.子程序 _按钮_缓存加载_被单击

.局部变量 缓存字典, 字典
.局部变量 宽度, 整数型
.局部变量 高度, 整数型
.局部变量 像素数据, 整数型

.如果真 (缓存字典.取成员 (“test.bmp”) ≠ 0)
    ' 从缓存中获取
    像素数据 = 缓存字典.取成员 (“test.bmp”)
.否则
    ' 从磁盘加载
    图像读取 (“test.bmp”, 宽度, 高度, 像素数据)
    缓存字典.赋值 (“test.bmp”, 像素数据)
.如果真结束

调试输出 (“图像数据地址:”, 像素数据)

缓存机制说明:

  • 使用字典缓存已加载的图像数据;
  • 避免重复加载相同图像;
  • 提升图像访问速度;
  • 适用于图像资源频繁访问的场景,如游戏、图像编辑器等。

总结

本章详细介绍了图像读取与加载的实现过程,从图像格式解析、内存结构设计到具体的 API 调用和性能优化策略。通过本章的学习,读者应掌握以下核心能力:

  • 理解 BMP、PNG 等常见图像格式的结构;
  • 能够解析图像文件头并提取图像信息;
  • 掌握图像在内存中的表示方式;
  • 实现图像读取功能并封装为函数;
  • 使用多线程技术提升图像加载效率;
  • 设计图像缓存机制避免重复加载。

下一章将深入探讨像素级图像比较技术,帮助读者实现更高级的图像识别功能。

4. 像素级图像比较技术

4.1 像素数据对比原理

4.1.1 RGB值对比方法

在图像处理中,像素是构成图像的基本单位。每个像素通常由红(Red)、绿(Green)、蓝(Blue)三个颜色通道组成,形成一个三维颜色空间中的点。RGB值对比是像素级图像比较的基础,其核心思想是将两个图像的对应像素进行逐点比较。

以下是一个简单的RGB像素值对比示例代码(使用易语言):

.版本 2

.子程序 比较像素RGB, 逻辑型
.参数 r1, 整数型
.参数 g1, 整数型
.参数 b1, 整数型
.参数 r2, 整数型
.参数 g2, 整数型
.参数 b2, 整数型
.参数 容差, 整数型

.局部变量 差值, 整数型

差值 = 取绝对值 (r1 - r2) + 取绝对值 (g1 - g2) + 取绝对值 (b1 - b2)
返回 (差值 ≤ 容差)

代码解析:

  • 该函数接收两个像素的RGB值和一个容差值作为参数。
  • 使用 取绝对值 函数计算每个颜色通道的差异。
  • 将三个通道的差值相加,如果总和小于等于容差,则认为两个像素颜色相似。
  • 返回值为逻辑型,表示是否匹配。

参数说明:

  • r1, g1, b1 :第一个像素的红、绿、蓝值。
  • r2, g2, b2 :第二个像素的红、绿、蓝值。
  • 容差 :允许的最大颜色差值总和,用于容忍细微差异。

这种逐点比较的方法虽然简单,但在处理大规模图像时效率较低,因此常用于小范围匹配或关键区域比较。

4.1.2 灰度值对比基础

将图像转换为灰度图后进行像素比较,可以显著减少计算量。灰度图像中每个像素只有一个亮度值,通常为0(黑)到255(白)之间的整数。

将RGB图像转换为灰度图像的常用公式如下:

Gray = 0.299 * R + 0.587 * G + 0.114 * B

以下是将RGB转换为灰度值的易语言函数示例:

.版本 2

.子程序 RGB转灰度, 整数型
.参数 r, 整数型
.参数 g, 整数型
.参数 b, 整数型

返回 (到整数 (0.299 × r + 0.587 × g + 0.114 × b))

代码解析:

  • 该函数接收一个像素的RGB值。
  • 使用加权平均法计算灰度值。
  • 返回整数型结果,表示该像素的灰度值。

参数说明:

  • r, g, b :输入的红、绿、蓝颜色值。

转换为灰度后,像素比较只需比较单个数值,计算效率更高。适用于对图像颜色细节不敏感但需要快速定位的场景。

4.2 像素级查找算法实现

4.2.1 逐点比对算法设计

逐点比对是最基础的像素级查找方法,其核心思想是遍历目标图像中的每一个像素点,与模板图像进行一一比对。如果某个区域的所有像素都匹配,则认为找到目标图像。

以下是一个逐点比对算法的易语言实现示例:

.版本 2

.子程序 查找图像位置, 点
.参数 目标图像, 图像
.参数 模板图像, 图像
.参数 容差, 整数型

.局部变量 x, 整数型
.局部变量 y, 整数型
.局部变量 tx, 整数型
.局部变量 ty, 整数型
.局部变量 匹配成功, 逻辑型

.结构 点
    x, 整数型
    y, 整数型
.结束结构

.循环首变量 x, 0, 目标图像.宽度 - 模板图像.宽度
    .循环首变量 y, 0, 目标图像.高度 - 模板图像.高度
        匹配成功 = 真
        .循环首变量 tx, 0, 模板图像.宽度 - 1
            .循环首变量 ty, 0, 模板图像.高度 - 1
                .局部变量 像素1, 整数型
                .局部变量 像素2, 整数型
                像素1 = 目标图像.取像素 (x + tx, y + ty)
                像素2 = 模板图像.取像素 (tx, ty)
                .如果真 (取绝对值 (像素1 - 像素2) > 容差)
                    匹配成功 = 假
                    退出循环
                .如果真结束
            .循环尾
            .如果真 (匹配成功 = 假)
                退出循环
            .如果真结束
        .循环尾
        .如果真 (匹配成功)
            返回 (创建结构体 (x, y))
        .如果真结束
    .循环尾

返回 (创建结构体 (-1, -1)) ' 表示未找到

代码解析:

  • 该函数用于在目标图像中查找模板图像的位置。
  • 使用四层循环,分别遍历目标图像的每个可能的起始位置 (x, y) 和模板图像的每个像素点 (tx, ty)
  • 如果所有像素在容差范围内匹配,则返回匹配位置 (x, y)
  • 否则返回 (-1, -1) 表示未找到。

参数说明:

  • 目标图像 :待查找的图像。
  • 模板图像 :用于匹配的小图像。
  • 容差 :允许的像素差异值。

此算法简单直观,但时间复杂度较高,适用于图像较小或精度要求较高的场景。

4.2.2 区域范围限定策略

为了提升查找效率,通常会对查找区域进行限定。例如:

  • 限定查找区域 :在目标图像中指定一个矩形区域进行查找,避免全图扫描。
  • 多级查找策略 :先进行粗略匹配,再在匹配区域内进行精确查找。

流程图:

graph TD
    A[开始] --> B[指定查找区域]
    B --> C[遍历区域中的每个点]
    C --> D[在该点处比对模板图像]
    D --> E{是否匹配?}
    E -->|是| F[记录坐标并返回]
    E -->|否| C
    F --> G[结束]
    C --> H{是否遍历完区域?}
    H -->|否| C
    H -->|是| I[返回未找到]

通过限定查找区域,可大幅减少无效比对,提升查找速度。

4.3 像素级查找性能分析

4.3.1 时间复杂度评估

像素级查找算法的时间复杂度主要取决于图像的尺寸和查找方式。

假设:

  • 目标图像大小为 $ M \times N $
  • 模板图像大小为 $ m \times n $
  • 每个像素比对时间为 $ O(1) $

则总时间复杂度为:

O((M - m + 1) \times (N - n + 1) \times m \times n)

这表明,图像越大、模板越大,算法执行时间呈指数级增长。对于大图像匹配任务,这种算法效率较低。

4.3.2 缓存机制优化比对效率

为了提升查找效率,可以引入缓存机制:

  • 像素缓存 :将目标图像和模板图像的像素数据一次性读取到数组中,避免多次调用图像API。
  • 提前终止机制 :一旦发现某个像素不匹配,立即跳过当前区域。
  • 滑动窗口优化 :利用前一窗口的比对结果,减少重复计算。

以下是一个像素缓存优化的易语言代码片段:

.版本 2

.子程序 预加载像素数据, 整数型, 公开
.参数 图像, 图像
.局部变量 缓存数组, 整数型, 数组

.局部变量 x, 整数型
.局部变量 y, 整数型

重新定义数组 (缓存数组, 假, 图像.宽度, 图像.高度)

.循环首变量 x, 0, 图像.宽度 - 1
    .循环首变量 y, 0, 图像.高度 - 1
        缓存数组 [x] [y] = 图像.取像素 (x, y)
    .循环尾
.循环尾

返回 缓存数组

代码解析:

  • 该函数将图像的像素数据缓存到二维数组中。
  • 后续查找时直接访问数组,避免频繁调用图像API。

参数说明:

  • 图像 :需要缓存像素的图像对象。
  • 缓存数组 :用于存储像素值的二维数组。

通过缓存机制,可以显著减少图像API调用次数,提高查找效率。

4.4 像素误差容忍机制

4.4.1 颜色容差设置

在实际图像比对中,由于光照变化、压缩失真等原因,完全相同的像素值可能并不存在。因此需要设置一个容差值,允许一定程度的误差。

容差设置方法:

  • 固定容差 :设定一个固定阈值,如容差=30。
  • 动态容差 :根据图像内容自动调整容差,如使用图像直方图分析。

示例代码:

.版本 2

.子程序 设置颜色容差, 整数型
.参数 基准颜色, 整数型
.参数 当前颜色, 整数型
.参数 容差, 整数型

返回 (取绝对值 (基准颜色 - 当前颜色) ≤ 容差)

参数说明:

  • 基准颜色 :模板图像中的像素颜色。
  • 当前颜色 :目标图像中的像素颜色。
  • 容差 :允许的最大颜色差值。

4.4.2 抗锯齿与模糊匹配

抗锯齿图像或模糊图像的像素颜色可能与模板存在偏差。为应对这种情况,可以采用以下策略:

  • 颜色平均法 :取一个区域的像素平均值进行比较。
  • 边缘模糊容忍 :对边缘像素放宽容差限制。
  • 模糊哈希算法 :使用感知哈希(aHash)等方法进行图像指纹比对。

示例表格:

方法 优点 缺点
固定容差 实现简单,速度快 对复杂图像效果不佳
动态容差 自适应能力强 实现复杂,计算量大
颜色平均法 对抗锯齿效果好 损失细节,可能误匹配
模糊哈希算法 鲁棒性强,抗干扰好 实现难度高,资源消耗大

通过引入误差容忍机制,可以有效提升图像比对的鲁棒性和适用范围。

5. 模板匹配与相似度计算方法

图像识别领域中,模板匹配是一项核心功能,尤其在自动化脚本、界面识别、游戏辅助开发中具有广泛应用。本章将深入探讨模板匹配的基本原理、实现方式及其优化策略,重点讲解如何通过相似度计算提高匹配的准确性和效率。我们将从最基础的滑动窗口匹配算法出发,逐步引入直方图匹配、特征点匹配等更高级的技术,并最终探讨多尺度匹配策略的实现方法。

5.1 模板匹配基本原理

模板匹配(Template Matching)是一种基于像素比对的图像识别方法,其核心思想是将一个小图像(模板图像)在大图像中滑动,计算每个位置的相似度,找到最佳匹配区域。

5.1.1 模板滑动匹配流程

模板滑动匹配是一种经典的图像识别技术,其基本流程如下:

  1. 加载模板图像与目标图像 :将模板图像与目标图像读入内存。
  2. 滑动窗口机制 :以模板图像的大小为窗口,在目标图像上逐像素滑动。
  3. 相似度计算 :在每个窗口位置计算模板与目标区域的相似度。
  4. 记录最佳匹配点 :根据相似度值找出最佳匹配位置。

该过程可以用如下Mermaid流程图表示:

graph TD
    A[开始] --> B[加载模板图像]
    B --> C[加载目标图像]
    C --> D[初始化滑动窗口]
    D --> E[在目标图像上滑动窗口]
    E --> F{是否到达图像边界?}
    F -- 否 --> G[计算当前位置相似度]
    G --> H[记录相似度值]
    H --> E
    F -- 是 --> I[找出最大相似度位置]
    I --> J[输出匹配坐标]
    J --> K[结束]

5.1.2 相似度计算公式解析

相似度计算是模板匹配的核心,常用的计算方法包括:

方法名称 公式 说明
平方差匹配(SQDIFF) $\sum (T(x,y) - I(x,y))^2$ 差值越小越相似,适合精确匹配
归一化平方差匹配(SQDIFF_NORMED) $\frac{\sum (T(x,y) - I(x,y))^2}{\sqrt{\sum T(x,y)^2 \cdot \sum I(x,y)^2}}$ 归一化处理,增强鲁棒性
相关系数匹配(CCOEFF) $\sum T(x,y) \cdot I(x,y)$ 值越大越相似
归一化相关系数匹配(CCOEFF_NORMED) $\frac{\sum T(x,y) \cdot I(x,y)}{\sqrt{\sum T(x,y)^2 \cdot \sum I(x,y)^2}}$ 更适合亮度变化场景
相关匹配(CCORR) $\sum T(x,y) \cdot I(x,y)$ 与相关系数类似,但不归一化

其中,$T(x,y)$为模板图像像素值,$I(x,y)$为目标图像像素值。

在易语言中,可以通过自定义函数实现相关匹配算法。例如,实现归一化相关系数匹配的代码如下:

.版本 2

.子程序 计算相关系数, 双精度小数型
.参数 模板数据, 字节集
.参数 目标数据, 字节集
.局部变量 i, 整数型
.局部变量 sumT, 双精度小数型
.局部变量 sumI, 双精度小数型
.局部变量 sumTI, 双精度小数型
.局部变量 sumT2, 双精度小数型
.局部变量 sumI2, 双精度小数型
.局部变量 length, 整数型

length = 取字节集长度 (模板数据)
.计次循环首 (length, i)
    sumT = sumT + 模板数据 [i]
    sumI = sumI + 目标数据 [i]
    sumTI = sumTI + 模板数据 [i] × 目标数据 [i]
    sumT2 = sumT2 + 模板数据 [i] ^ 2
    sumI2 = sumI2 + 目标数据 [i] ^ 2
.计次循环尾 ()

返回 ( (length × sumTI - sumT × sumI) / ( (length × sumT2 - sumT ^ 2) × (length × sumI2 - sumI ^ 2) ) ^ 0.5 )

代码逐行分析:

  • 第1~3行 :定义函数名称、返回类型和参数。模板数据与目标数据均为字节集。
  • 第4~8行 :定义局部变量,用于存储累加值。
  • 第9~15行 :遍历每个像素点,计算模板与目标图像的累加值。
  • 第16~17行 :代入公式,返回归一化相关系数值。

该函数返回的值范围在 -1 到 1 之间,越接近 1 表示匹配度越高。

5.2 基于直方图的图像匹配

在模板匹配中,像素级匹配容易受到光照变化、旋转、缩放等因素影响。基于直方图的图像匹配是一种更为鲁棒的方法,通过统计图像的灰度或颜色分布进行匹配。

5.2.1 图像直方图构建

图像直方图(Image Histogram)是一种表示图像中像素值分布的统计图表。对于灰度图像,通常使用 0~255 的灰度等级作为横坐标,统计每个灰度值出现的次数作为纵坐标。

构建图像直方图的步骤如下:

  1. 图像灰度化处理 :将彩色图像转换为灰度图像。
  2. 遍历像素点 :统计每个灰度值出现的频率。
  3. 归一化处理 :将统计结果归一化为 0~1 的概率分布。

在易语言中,可以通过如下代码构建灰度图像的直方图:

.版本 2

.子程序 构建直方图, 双精度小数型, 公开, 返回归一化后的直方图数组
.参数 图像数据, 字节集
.局部变量 直方图, 双精度小数型, "256"
.局部变量 i, 整数型
.局部变量 灰度值, 整数型
.局部变量 总像素数, 整数型

总像素数 = 取字节集长度 (图像数据)
.计次循环首 (总像素数, i)
    灰度值 = 图像数据 [i]
    直方图 [灰度值 + 1] = 直方图 [灰度值 + 1] + 1
.计次循环尾 ()

.计次循环首 (256, i)
    直方图 [i] = 直方图 [i] / 总像素数
.计次循环尾 ()

返回 (直方图)

代码分析:

  • 第1~3行 :定义函数名、返回类型和参数。图像数据是字节集格式的灰度图像。
  • 第4~6行 :定义直方图数组、循环变量和灰度值变量。
  • 第7~10行 :遍历每个像素点,统计灰度值出现的次数。
  • 第11~14行 :将统计值归一化为概率分布。
  • 第15行 :返回归一化后的直方图数组。

5.2.2 直方图相似度比较

构建完两个图像的直方图后,下一步是计算它们之间的相似度。常用的方法包括:

  • 卡方距离(Chi-Square Distance)
    $$
    D = \sum \frac{(H1[i] - H2[i])^2}{H1[i] + H2[i]}
    $$
  • 相关系数(Correlation)
    $$
    R = \frac{\sum (H1[i] - \bar{H1})(H2[i] - \bar{H2})}{\sqrt{\sum (H1[i] - \bar{H1})^2 \cdot \sum (H2[i] - \bar{H2})^2}}
    $$
  • 巴氏距离(Bhattacharyya Distance)
    $$
    D = 1 - \sum \sqrt{H1[i] \cdot H2[i]}
    $$

以下代码实现卡方距离计算:

.版本 2

.子程序 计算卡方距离, 双精度小数型
.参数 直方图1, 双精度小数型, "256"
.参数 直方图2, 双精度小数型, "256"
.局部变量 i, 整数型
.局部变量 距离, 双精度小数型

.计次循环首 (256, i)
    距离 = 距离 + (直方图1 [i] - 直方图2 [i]) ^ 2 / (直方图1 [i] + 直方图2 [i] + 0.00001)
.计次循环尾 ()

返回 (距离)

代码分析:

  • 第1~3行 :定义函数名、参数和返回类型。
  • 第4~5行 :定义循环变量和距离变量。
  • 第6~8行 :遍历直方图,计算卡方距离。
  • 第9行 :返回计算结果。

5.3 基于特征点的匹配方法

特征点匹配是一种更为高级的图像匹配方法,能够应对图像的旋转、缩放、光照变化等复杂情况。OpenCV中常用的特征点检测算法包括SIFT、SURF、ORB等。在易语言中,可以借助调用DLL的方式实现特征点匹配。

5.3.1 关键点检测与描述

关键点检测是特征匹配的第一步,其目标是找出图像中的显著特征点,并生成对应的特征描述子。

在OpenCV中,SIFT算法是经典的特征点检测与描述方法。其流程如下:

  1. 尺度空间极值检测 :找出在不同尺度下稳定的特征点。
  2. 关键点定位 :去除低对比度和边缘响应点。
  3. 方向赋值 :为每个特征点分配一个主方向,增强旋转不变性。
  4. 特征描述 :生成128维的特征向量。

在易语言中,可以通过调用外部DLL函数实现SIFT特征提取。例如:

.版本 2

.子程序 提取SIFT特征, 逻辑型
.参数 图像路径, 文本型
.局部变量 dll, 整数型
.局部变量 特征点, 文本型

dll = 调用外部函数 ("opencv_contrib.dll", "extract_sift_features", "s", "s", 图像路径)
特征点 = 读取字符串 (dll)
调试输出 (特征点)

返回 (真)

代码分析:

  • 第1~3行 :定义子程序名、参数和返回类型。
  • 第4~5行 :定义DLL句柄和特征点变量。
  • 第6行 :调用外部DLL函数提取SIFT特征。
  • 第7行 :读取返回的特征点字符串。
  • 第8行 :输出特征点信息。
  • 第9行 :返回执行状态。

5.3.2 特征向量匹配算法

特征匹配的核心是将两组特征向量进行比对,找出最相似的对应关系。常用的方法包括:

  • 最近邻匹配(Nearest Neighbor)
  • K近邻匹配(KNN Matching)
  • FLANN匹配(Fast Library for Approximate Nearest Neighbors)

以下是一个使用FLANN匹配的伪代码逻辑:

.版本 2

.子程序 匹配特征向量, 逻辑型
.参数 模板特征, 文本型
.参数 目标特征, 文本型
.局部变量 匹配结果, 文本型

匹配结果 = 调用外部函数 ("opencv_contrib.dll", "flann_match", "ss", 模板特征, 目标特征)
调试输出 (匹配结果)

返回 (真)

代码分析:

  • 第1~3行 :定义函数名、参数和返回类型。
  • 第4行 :定义匹配结果变量。
  • 第5行 :调用外部DLL函数进行FLANN匹配。
  • 第6行 :输出匹配结果。
  • 第7行 :返回执行状态。

5.4 多尺度模板匹配策略

在实际应用中,目标图像中可能存在不同尺寸的模板对象。多尺度模板匹配通过构建图像金字塔,实现不同分辨率下的匹配,提高识别率。

5.4.1 图像金字塔构建

图像金字塔(Image Pyramid)是一种图像多尺度表示方法,通过不断缩小图像分辨率构建多层图像。

构建图像金字塔的步骤如下:

  1. 初始化原始图像
  2. 按比例缩放图像 (通常为0.5倍)。
  3. 重复缩放直到图像尺寸小于模板图像
  4. 将每一层图像保存为金字塔结构

在易语言中,可以使用GDI+或调用OpenCV DLL实现图像缩放:

.版本 2

.子程序 构建图像金字塔, 逻辑型
.参数 原始图像, 图片框
.局部变量 当前图像, 图片框
.局部变量 缩放比例, 双精度小数型
.局部变量 图像层数, 整数型

缩放比例 = 0.5
图像层数 = 0

当前图像 = 原始图像
.循环判断首 (取图片宽度 (当前图像) > 取模板宽度 () 且 取图片高度 (当前图像) > 取模板高度 ())
    图像层数 = 图像层数 + 1
    当前图像 = 缩放图片 (当前图像, 缩放比例, 缩放比例)
    调试输出 ("图像层:", 图像层数, " 尺寸:", 取图片宽度 (当前图像), "x", 取图片高度 (当前图像))
.循环判断尾 ()

返回 (真)

代码分析:

  • 第1~3行 :定义子程序名、参数和局部变量。
  • 第4~6行 :设置缩放比例和图像层数。
  • 第7~10行 :循环缩放图像,直到图像尺寸小于模板图像。
  • 第11行 :输出每层图像的信息。
  • 第12行 :返回执行状态。

5.4.2 多分辨率查找优化

多分辨率查找策略的核心是在每一层图像中进行模板匹配,然后将结果映射回原始图像坐标。

实现步骤如下:

  1. 构建图像金字塔
  2. 从最高层(最小图像)开始匹配
  3. 若匹配成功,将其坐标映射回原始图像
  4. 若未匹配成功,继续下一层图像匹配

此方法可显著提高查找效率,特别是在模板图像较小或目标图像较大的情况下。

6. 图像坐标定位与转换

6.1 屏幕坐标与图像坐标的映射

在图像识别与自动化操作中,屏幕坐标与图像坐标的映射是实现准确定位的基础。屏幕坐标通常以左上角为原点 (0,0) ,向右为 X 轴正方向,向下为 Y 轴正方向;而图像坐标则可能因图像加载方式不同而有所变化。

6.1.1 坐标系统差异分析

坐标系统 原点位置 X轴方向 Y轴方向
屏幕坐标 左上角 向右 向下
图像坐标 左上角 向右 向下

虽然二者方向一致,但图像坐标可能因控件缩放、窗口移动等原因导致与屏幕坐标存在偏移。例如,当图像被加载到窗口控件中并进行了缩放,图像坐标将与屏幕坐标的像素比例不同。

6.1.2 坐标转换公式推导

若图像以比例 (scale_x, scale_y) 缩放,则图像坐标 (img_x, img_y) 对应的屏幕坐标 (screen_x, screen_y) 可通过如下公式转换:

screen_x = img_x * scale_x
screen_y = img_y * scale_y

若图像存在偏移量 (offset_x, offset_y) (如窗口边框),则:

screen_x = img_x * scale_x + offset_x
screen_y = img_y * scale_y + offset_y

6.2 查找结果的坐标提取

图像匹配完成后,需提取匹配区域的坐标信息,以便后续操作使用。

6.2.1 匹配区域坐标获取

假设使用像素级查找算法返回匹配位置 (x, y) ,该位置通常为模板图像左上角在目标图像中的位置。例如:

匹配位置.x = 120
匹配位置.y = 85

6.2.2 坐标数据结构设计

为统一管理坐标信息,可设计结构体或类来封装:

结构体 坐标结构
    成员 x, 整数型
    成员 y, 整数型
    成员 宽度, 整数型
    成员 高度, 整数型
结束结构体

通过该结构,可以同时记录匹配区域的起始点 (x, y) 以及区域大小 (宽度, 高度)

6.3 坐标偏移与修正策略

图像窗口或控件的位置变动会导致坐标偏移,影响点击或操作的准确性。需引入动态校正机制。

6.3.1 窗口移动导致的偏移

当目标图像所在的窗口被移动时,图像的屏幕位置发生变化,此时原有的坐标已失效。例如:

原窗口位置 = 取窗口位置(目标窗口句柄)
新窗口位置 = 取窗口位置(目标窗口句柄)
偏移量.x = 新窗口位置.x - 原窗口位置.x
偏移量.y = 新窗口位置.y - 原窗口位置.y

6.3.2 动态校正机制设计

每次图像查找后,可记录当前窗口位置,并在调用操作函数前进行坐标修正:

函数 修正坐标(原始坐标, 窗口位置)
    修正后坐标.x = 原始坐标.x + 窗口位置.x
    修正后坐标.y = 原始坐标.y + 窗口位置.y
    返回 修正后坐标
结束函数

6.4 多图匹配结果整合

在某些场景中,可能需要同时查找多个图像模板,此时需要对多个匹配结果进行整合处理。

6.4.1 多个匹配区域合并

假设通过循环查找多个图像模板,返回多个坐标结构体,可将其存入列表中:

匹配结果列表 = 创建列表()
循环首元素 模板列表, 模板
    匹配坐标 = 查找图像(模板)
    如果匹配坐标不为空
        添加成员(匹配结果列表, 匹配坐标)
    结束如果
循环尾

6.4.2 结果排序与筛选逻辑

为提高操作效率,可对匹配结果进行排序和筛选:

函数 排序筛选结果(结果列表)
    排序方式 = 按照 x + y 升序
    筛选条件 = 面积 > 100
    返回 排序后的列表
结束函数

通过排序,可以优先选择靠前或靠左的匹配区域;通过筛选,可排除面积过小的误匹配区域。

此外,可使用 Mermaid 流程图描述整个坐标定位与转换的逻辑流程:

graph TD
    A[图像匹配完成] --> B{是否存在多个匹配区域?}
    B -->|是| C[提取所有匹配坐标]
    B -->|否| D[仅提取单一坐标]
    C --> E[合并坐标至结果列表]
    D --> F[计算窗口偏移量]
    E --> G[根据窗口位置修正坐标]
    G --> H[结果排序与筛选]
    H --> I[输出最终坐标]

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:易语言是一种以中文语法为基础的编程语言,降低了编程门槛,适合初学者快速上手。本项目围绕“易语言找图”展开,利用位图操作支持库实现图像处理与识别功能,涵盖图像读取、模板匹配、像素比较、坐标定位等关键技术。适用于自动化测试、游戏辅助等场景,通过完整源码讲解帮助开发者掌握图像识别的实现流程与优化技巧。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐