附录:调用示例 / 错误码 / 线程安全 / 调用流程
版本:1.26.0613
目录
1. 调用示例
1.1 C/C++ 示例
cpp
#include "include/export_dll.h"
#include <stdio.h>
#include <string.h>
int main() {
// ===== 1. 通用工具 =====
printf("版本: %s\n", version());
printf("DLL目录: %s\n", getDllDir());
// ===== 2. YOLOv8 检测 =====
int ret = loadYolov8Model("detector", "yolov8n.onnx");
if (ret == 1) {
printf("模型加载成功\n");
setYolov8Sim("detector", 0.6f);
setYolov8Iou("detector", 0.45f);
const char* result = yolov8Detect("detector", "test.jpg");
printf("检测结果: %s\n", result);
result = yolov8DetectDraw("detector", "test.jpg", "result.jpg");
printf("绘制结果: %s\n", result);
}
// ===== 3. OCR 识别 =====
ret = initOcrv4(4);
if (ret == 1) {
OcrParam param;
param.sim = 0.6f;
param.use_angle_cls = 1;
const char* text = ocrv4Detect("text.png", ¶m);
printf("OCR结果: %s\n", text);
printf("OCR中文: %s\n", utf8ToGBK(text));
}
// ===== 4. 找图(多目标) =====
const char* matches = findPic("screen.png", "icon.png", 1, 10, 0.8f);
printf("找图结果: %s\n", matches);
matches = findPicOut("screen.png", "icon.png", 1, 10, 0.8f, "marked.png");
// ===== 5. 纯模板匹配(单目标) =====
const char* tm = templateMatch("screen.png", "icon.png", 0.8f, 0, 1);
printf("模板匹配: %s\n", tm);
tm = templateMatch("screen.png", "icon.png", 0.8f, 1, 2);
printf("快速匹配: %s\n", tm);
// ===== 6. 多模板匹配 =====
const char* multi = templateMatchMulti("screen.png",
"icon1.png, icon2.png, icon3.png", 0.8f, 0, 1);
printf("多模板匹配: %s\n", multi);
// ===== 7. 图片灰度处理 =====
const char* grayRet = imageToGray("photo.jpg", "");
printf("灰度处理: %s\n", grayRet);
grayRet = imageToGray("photo.jpg", "C:/out/gray.jpg");
printf("灰度处理(指定路径): %s\n", grayRet);
// ===== 8. 图像处理接口 =====
const char* sc = screenCapture("screenshot.png", 0, 0, 1920, 1080);
printf("截图: %s\n", sc);
const char* crop = imageCrop("photo.jpg", 100, 100, 200, 200, "crop.jpg");
printf("裁剪: %s\n", crop);
const char* resize = imageResize("photo.jpg", 640, 480, "resized.jpg");
printf("缩放: %s\n", resize);
const char* color = findColor("screen.png", "FF0000", 10);
printf("找色: %s\n", color);
const char* pixel = getPixelColor("screen.png", 100, 200);
printf("像素色: %s\n", pixel);
const char* sim = imageCompare("img1.png", "img2.png");
printf("相似度: %s\n", sim);
return 0;
}1.2 C# 示例
csharp
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("Lkinfer32.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr version();
[DllImport("Lkinfer32.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr getLastError();
[DllImport("Lkinfer32.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int loadYolov8Model(string name, string modelPath);
[DllImport("Lkinfer32.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr yolov8Detect(string name, string imgPath);
[DllImport("Lkinfer32.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int initOcrv4(int nThreads);
[DllImport("Lkinfer32.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr ocrv4Detect(string img_path, ref OcrParam param);
[DllImport("Lkinfer32.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr findPic(string img_path, string target_path,
int model, int number, float sim);
[DllImport("Lkinfer32.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr templateMatch(string imgPath, string templPath,
float threshold, int mode, int method);
[DllImport("Lkinfer32.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr templateMatchMulti(string imgPath, string templPaths,
float threshold, int mode, int method);
[DllImport("Lkinfer32.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr utf8ToGBK(string u8);
[DllImport("Lkinfer32.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr imageToGray(string srcPath, string outPath);
[DllImport("Lkinfer32.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr screenCapture(string outPath, int left, int top,
int width, int height);
[DllImport("Lkinfer32.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr imageCrop(string srcPath, int x, int y,
int w, int h, string outPath);
[DllImport("Lkinfer32.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr imageResize(string srcPath, int width,
int height, string outPath);
[DllImport("Lkinfer32.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr findColor(string imgPath, string colorHex,
int tolerance);
[DllImport("Lkinfer32.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr getPixelColor(string imgPath, int x, int y);
[DllImport("Lkinfer32.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr imageCompare(string img1, string img2);
[StructLayout(LayoutKind.Sequential)]
public struct OcrParam
{
public int padding;
public int max_size;
public float sim;
public float box_thresh;
public float un_clip_ratio;
public int use_angle_cls;
public int most_angle;
}
static string PtrToString(IntPtr ptr)
{
return ptr != IntPtr.Zero ? Marshal.PtrToStringAnsi(ptr) ?? "" : "";
}
static void Main()
{
Console.WriteLine("版本: " + PtrToString(version()));
// YOLOv8
int ret = loadYolov8Model("detector", "yolov8n.onnx");
if (ret == 1)
{
string result = PtrToString(yolov8Detect("detector", "test.jpg"));
Console.WriteLine("检测: " + result);
}
// OCR
ret = initOcrv4(4);
if (ret == 1)
{
OcrParam param = new OcrParam();
param.sim = 0.6f;
param.use_angle_cls = 1;
string text = PtrToString(ocrv4Detect("text.jpg", ref param));
Console.WriteLine("OCR: " + text);
}
// 找图
string matches = PtrToString(findPic("screen.png", "icon.png", 1, 10, 0.8f));
Console.WriteLine("找图: " + matches);
// 模板匹配
string tm = PtrToString(templateMatch("screen.png", "icon.png", 0.8f, 0, 1));
Console.WriteLine("匹配: " + tm);
// 多模板匹配
string multi = PtrToString(templateMatchMulti("screen.png",
"icon1.png,icon2.png,icon3.png", 0.8f, 0, 1));
Console.WriteLine("多模板: " + multi);
// 截图
string sc = PtrToString(screenCapture("screenshot.png", 0, 0, 1920, 1080));
Console.WriteLine("截图: " + sc);
// 裁剪
string crop = PtrToString(imageCrop("photo.jpg", 100, 100, 200, 200, "crop.jpg"));
Console.WriteLine("裁剪: " + crop);
// 缩放
string resize = PtrToString(imageResize("photo.jpg", 640, 480, "resized.jpg"));
Console.WriteLine("缩放: " + resize);
// 找色
string color = PtrToString(findColor("screen.png", "FF0000", 10));
Console.WriteLine("找色: " + color);
// 像素颜色
string pixel = PtrToString(getPixelColor("screen.png", 100, 200));
Console.WriteLine("像素色: " + pixel);
// 图片相似度
string sim = PtrToString(imageCompare("img1.png", "img2.png"));
Console.WriteLine("相似度: " + sim);
}
}1.3 Python 示例
python
import ctypes
import json
from ctypes import c_char_p, c_int, c_float, Structure, POINTER, byref
# 加载 DLL
dll = ctypes.CDLL("Lkinfer32.dll")
dll.version.restype = c_char_p
dll.getLastError.restype = c_char_p
dll.utf8ToGBK.restype = c_char_p
dll.yolov8Detect.restype = c_char_p
dll.ocrv4Detect.restype = c_char_p
dll.findPic.restype = c_char_p
dll.templateMatch.restype = c_char_p
# YOLOv8
dll.loadYolov8Model.argtypes = [c_char_p, c_char_p]
dll.loadYolov8Model.restype = c_int
dll.yolov8Detect.argtypes = [c_char_p, c_char_p]
dll.setYolov8Sim.argtypes = [c_char_p, c_float]
# OCR
dll.initOcrv4.argtypes = [c_int]
dll.initOcrv4.restype = c_int
dll.utf8ToGBK.argtypes = [c_char_p]
# findPic
dll.findPic.argtypes = [c_char_p, c_char_p, c_int, c_int, c_float]
# 纯模板匹配
dll.templateMatch.argtypes = [c_char_p, c_char_p, c_float, c_int, c_int]
# 多模板匹配
dll.templateMatchMulti.argtypes = [c_char_p, c_char_p, c_float, c_int, c_int]
dll.templateMatchMulti.restype = c_char_p
# 灰度处理
dll.imageToGray.argtypes = [c_char_p, c_char_p]
dll.imageToGray.restype = c_char_p
# 屏幕截图
dll.screenCapture.argtypes = [c_char_p, c_int, c_int, c_int, c_int]
dll.screenCapture.restype = c_char_p
# 裁剪
dll.imageCrop.argtypes = [c_char_p, c_int, c_int, c_int, c_int, c_char_p]
dll.imageCrop.restype = c_char_p
# 缩放
dll.imageResize.argtypes = [c_char_p, c_int, c_int, c_char_p]
dll.imageResize.restype = c_char_p
# 找色
dll.findColor.argtypes = [c_char_p, c_char_p, c_int]
dll.findColor.restype = c_char_p
# 取像素颜色
dll.getPixelColor.argtypes = [c_char_p, c_int, c_int]
dll.getPixelColor.restype = c_char_p
# 图片相似度
dll.imageCompare.argtypes = [c_char_p, c_char_p]
dll.imageCompare.restype = c_char_p
class OcrParam(Structure):
_fields_ = [
("padding", c_int),
("max_size", c_int),
("sim", c_float),
("box_thresh", c_float),
("un_clip_ratio", c_float),
("use_angle_cls", c_int),
("most_angle", c_int),
]
dll.ocrv4Detect.argtypes = [c_char_p, POINTER(OcrParam)]
dll.ocrv4Detect.restype = c_char_p
print(f"版本: {dll.version().decode()}")
# YOLOv8
ret = dll.loadYolov8Model(b"detector", b"yolov8n.onnx")
if ret == 1:
dll.setYolov8Sim(b"detector", c_float(0.6))
result = dll.yolov8Detect(b"detector", b"test.jpg").decode()
data = json.loads(result)
for obj in data:
print(f" 发现 {obj['name']} 在 ({obj['x']}, {obj['y']})")
# OCR
ret = dll.initOcrv4(4)
if ret == 1:
param = OcrParam(sim=0.6, use_angle_cls=1)
text = dll.ocrv4Detect(b"text.jpg", byref(param)).decode()
print(f"OCR: {dll.utf8ToGBK(text.encode()).decode('gbk')}")
# 找图
matches = dll.findPic(b"screen.png", b"icon.png", 1, 10, 0.8).decode()
print(f"找图: {matches}")
# 纯模板匹配
tm = dll.templateMatch(b"screen.png", b"icon.png", 0.8, 0, 1).decode()
print(f"匹配: {tm}")
result = json.loads(tm)
if result["matched"]:
print(f" 位置: ({result['x']}, {result['y']}), 分值: {result['score']}")
# 多模板匹配
multi = dll.templateMatchMulti(b"screen.png",
b"icon1.png,icon2.png,icon3.png", 0.8, 0, 1).decode()
print(f"多模板: {multi}")
results = json.loads(multi)
for key in sorted(results):
r = results[key]
print(f" {key}: matched={r['matched']}, score={r['score']}")
# 灰度处理
gray = dll.imageToGray(b"photo.jpg", b"").decode()
print(f"灰度: {gray}")
# 截图
sc = dll.screenCapture(b"screenshot.png", 0, 0, 1920, 1080).decode()
print(f"截图: {sc}")
# 裁剪
crop = dll.imageCrop(b"photo.jpg", 100, 100, 200, 200, b"crop.jpg").decode()
print(f"裁剪: {crop}")
# 缩放
resized = dll.imageResize(b"photo.jpg", 640, 480, b"resized.jpg").decode()
print(f"缩放: {resized}")
# 找色
color = dll.findColor(b"screen.png", b"FF0000", 10).decode()
print(f"找色: {color}")
# 像素颜色
pixel = dll.getPixelColor(b"screen.png", 100, 200).decode()
print(f"像素色: {pixel}")
# 图片相似度
sim = dll.imageCompare(b"img1.png", b"img2.png").decode()
print(f"相似度: {sim}")2. 错误码与处理
2.1 统一错误码体系
2.1.1 通用错误码表
| 返回码 | 含义 | 说明 |
|---|---|---|
1 | 成功 | 操作正常完成 |
0 | 一般性失败 | 文件不存在、模型不存在、参数错误等 |
-1 | 原图不存在 | 输入图片路径无效或文件无法读取 |
-2 | 模板/目标图不存在 | 模板图片路径无效或文件无法读取 |
2 | 模型不存在 | YOLOv8 指定名称的模型未加载 |
3 | 模型不存在(等同上) | 部分旧接口使用此码 |
4 | 运行时异常 | 内部异常,调用 getLastError() 获取详细错误描述 |
"[]" | 无匹配结果 | findPic / yolov8Detect 未检测到目标 |
"{}" | 无信息/空对象 | getYolov8Info / templateMatchMulti 无结果 |
2.1.2 各模块错误码对照
A. 通用工具(均返回整数/字符串)
| 函数 | 成功 | 失败 |
|---|---|---|
version() | 版本字符串 | 永不失败 |
getDllDir() | 目录路径 | 空字符串 |
getLastError() | 错误描述 | 空字符串(无错误) |
utf8ToGBK(u8) | GBK 字符串 | 永不失败 |
clearCache() | 1 | 永不失败 |
log_off() | 1 | 永不失败 |
B. YOLOv8 检测(返回整数)
| 函数 | 成功 | 模型不存在 | 异常 |
|---|---|---|---|
loadYolov8Model | 1 | 0(文件不存在) | 4 |
reLoadYolov8Model | 1 | 3(原模型不存在) | 4 |
setYolov8Sim | 1 | 0 | — |
setYolov8Iou | 1 | 0 | — |
existsYolov8Name | 1(存在) / 0(不存在) | — | — |
C. YOLOv8 检测(返回 JSON 字符串)
| 函数 | 成功 | 图片不存在 | 模型不存在 | 无结果 | 异常 |
|---|---|---|---|---|---|
yolov8Detect | JSON 数组 | "0" | "2" | "[]" | "4" |
yolov8DetectDraw | JSON 数组 | "0" | "2" | "[]" | "4" |
getYolov8Info | JSON 对象 | — | "{}" | — | "4" |
getAllYolov8Name | JSON 数组 | — | — | "[]" | — |
D. OCR 文字识别
| 函数 | 成功 | 失败/异常 |
|---|---|---|
initOcrv4(nThreads) | 1 | 4 |
ocrv4Detect | JSON 字符串 | "4"(异常) |
ocrv4DetectParam | JSON 字符串 | "4"(异常) |
E. 模板匹配找图(findPic 系列)
| 函数 | 成功 | 原图不存在 | 模板不存在 | 无匹配 |
|---|---|---|---|---|
findPic | JSON 数组 | "-1" | "-2" | "[]" |
findPicDraw | JSON 数组 | "-1" | "-2" | "[]" |
findPicOut | JSON 数组 | "-1" | "-2" | "[]" |
F. 纯模板匹配(templateMatch 系列)
| 函数 | 成功 | 一般性失败 |
|---|---|---|
templateMatch | {"matched":true/false, ...} | {"matched":false, "error":"原因"} |
templateMatchMulti | {"in_0":{...}, ...} | "{}" |
imageToGray | {"success":true} | {"success":false, "error":"原因"} |
templateMatch 的 error 字段取值:
| error 值 | 触发条件 |
|---|---|
"参数为空" | imgPath 或 templPath 为 nullptr |
"阈值范围错误" | threshold 不在 [0, 1] 范围 |
"色彩模式参数错误" | mode 不是 0 或 1 |
"算法模式参数错误" | method 不是 1~6 |
"主图不存在" | 主图文件无法读取 |
"模板图不存在" | 模板文件无法读取 |
"模板图大于主图" | 模板尺寸超过主图 |
"未找到匹配" | 匹配分值低于阈值 |
templateMatchMulti 单条错误:"模板图无效"(该模板文件不存在或尺寸超过主图)。
imageToGray 的 error 字段取值:
| error 值 | 触发条件 |
|---|---|
"原图片路径为空" | srcPath 为 nullptr 或空字符串 |
"原图片不存在或无法读取" | 图片文件无法读取 |
"不支持的图片通道数" | 图片通道数不是 1/3/4 |
"保存图片失败" | imwrite 写入失败 |
G. 图像处理接口
所有图像处理接口统一返回 {"success":true/false, ...}。
| error 值 | 触发函数 | 触发条件 |
|---|---|---|
"输出路径为空" | screenCapture / imageCrop / imageResize | outPath 为 nullptr 或空字符串 |
"截图宽高必须大于0" | screenCapture | width ≤ 0 或 height ≤ 0 |
"保存截图失败" | screenCapture | imwrite 写入失败 |
"原图片路径为空" | imageCrop / imageResize | srcPath 为 nullptr 或空字符串 |
"裁剪宽高必须大于0" | imageCrop | w ≤ 0 或 h ≤ 0 |
"原图片不存在或无法读取" | imageCrop / imageResize / findColor / getPixelColor / imageCompare | imread 返回空图 |
"裁剪区域超出图片范围" | imageCrop | ROI 超出图像边界 |
"保存裁剪图片失败" | imageCrop | imwrite 写入失败 |
"目标宽高必须大于0" | imageResize | width ≤ 0 或 height ≤ 0 |
"保存缩放图片失败" | imageResize | imwrite 写入失败 |
"图片路径为空" | findColor / getPixelColor / imageCompare | 路径为 nullptr 或空字符串 |
"颜色值为空" | findColor | colorHex 为 nullptr 或空字符串 |
"颜色值格式错误,需6位十六进制" | findColor | colorHex 格式不正确 |
"坐标超出图片范围" | getPixelColor | x/y 超出图像边界 |
2.2 错误处理最佳实践
场景 1:整数返回接口
cpp
int ret = loadYolov8Model("detector", "model.onnx");
if (ret != 1) {
if (ret == 4) {
fprintf(stderr, "异常: %s\n", getLastError());
} else if (ret == 0) {
fprintf(stderr, "模型文件不存在\n");
}
return -1;
}场景 2:JSON 字符串接口(yolov8Detect / findPic)
cpp
const char* result = yolov8Detect("detector", "test.jpg");
if (strcmp(result, "0") == 0) {
printf("图片不存在\n");
} else if (strcmp(result, "2") == 0) {
printf("模型不存在\n");
} else if (strcmp(result, "4") == 0) {
printf("异常: %s\n", getLastError());
} else if (strcmp(result, "[]") != 0) {
printf("检测到目标: %s\n", result);
}场景 3:templateMatch 统一 JSON 格式
cpp
const char* tm = templateMatch("screen.png", "icon.png", 0.8f, 0, 1);
// 直接解析 JSON 判断 matched 字段场景 4:imageToGray 统一 JSON 格式
cpp
const char* ret = imageToGray("photo.jpg", "");
// 解析 JSON 判断 success 字段3. 线程安全说明
3.1 线程安全保证
| 模块 | 安全级别 | 说明 |
|---|---|---|
| YOLOv8 | ✅ 线程安全 | 每个模型名称有独立的互斥锁。不同模型可并发调用 |
| OCR | ⚠️ 单例安全 | 全局单例 OcrLite 实例,建议外部加锁同步 |
| 找图 | ✅ 无状态 | 所有函数均为无状态调用,线程安全 |
| 模板匹配 | ✅ 无状态 | 线程安全(缓存字符串为独立 static 变量) |
| 灰度处理 | ✅ 无状态 | 线程安全 |
| 图像处理 | ✅ 无状态 | 截图/裁剪/缩放/颜色查找/对比均为无状态调用,线程安全 |
3.2 多线程建议
cpp
// 安全:不同模型可并发
std::thread([] { yolov8Detect("model1", "img1.jpg"); });
std::thread([] { yolov8Detect("model2", "img2.jpg"); });
// OCR 建议外部同步
std::mutex ocr_mtx;
std::thread([&] {
std::lock_guard<std::mutex> lock(ocr_mtx);
ocrv4Detect("img.jpg", ¶m);
});
std::thread([&] {
std::lock_guard<std::mutex> lock(ocr_mtx);
ocrv4Detect("img2.jpg", ¶m);
});4. 调用流程
4.1 YOLOv8 检测流程
1. loadYolov8Model("detector", "yolov8n.onnx") // 加载模型
│
2. setYolov8Sim("detector", 0.6) // 可选:调参
│
3. yolov8Detect("detector", "test.jpg") // 执行检测
│
4. 解析 JSON 结果 // 处理结果4.2 OCR 识别流程
1. initOcrv4(4) // 初始化(只需一次)
│
2. 构造 OcrParam 结构体 // 设置参数
│
3. ocrv4Detect("text.jpg", ¶m) // 执行识别
│
4. utf8ToGBK(结果) → 显示中文 // 编码转换(可选)4.3 模板匹配与图像处理流程
1. templateMatch("screen.png", "icon.png", 0.8, 0, 1) // 通用匹配
└── 返回 {"matched":true, "x":100, "y":200, "score":0.95}
2. templateMatch("screen.png", "icon.png", 0.8, 1, 2) // 灰度 + SQDIFF(最快)
3. templateMatch("screen.png", "icon.png", 0.7, 0, 1) // 彩色 + CCOEFF_NORMED
4. templateMatchMulti("screen.png", "btn1.png, btn2.png, btn3.png", 0.8, 0, 1)
└── 返回 {"in_0":{...}, "in_1":{...}, "in_2":{...}}
5. imageToGray("photo.jpg", "") // 灰度处理(自动命名)
└── 生成 photo_gray.jpg,返回 {"success":true}
6. screenCapture("screenshot.png", 0, 0, 1920, 1080) // 屏幕截图
└── 返回 {"success":true, "path":"screenshot.png"}
7. imageCrop("photo.jpg", 100, 100, 200, 200, "crop.jpg") // 裁剪
└── 返回 {"success":true}
8. imageResize("photo.jpg", 640, 480, "resized.jpg") // 缩放
└── 返回 {"success":true}
9. findColor("screen.png", "FF0000", 10) // 找色
└── 返回 {"success":true, "count":5, "points":[[x1,y1],...]}
10. getPixelColor("screen.png", 100, 200) // 取像素颜色
└── 返回 {"success":true, "color":"FF0000", "hex":"#FF0000"}
11. imageCompare("img1.png", "img2.png") // 图片相似度
└── 返回 {"success":true, "similarity":0.95}提示:所有返回字符串(
const char*)为内部静态缓存,调用者无需释放内存。但在下一次调用同一函数前,需及时取出数据或拷贝。