nodejs项目使用tesseract的文字识别功能

木头的喵喵拖孩

记录一下在 Node.js 项目中使用 tesseract 的文字识别功能。

安装 Tesseract.js

使用 Node.js 版本 16.19.1

1
2
3
# 指定版本,成功率更高
# 还需要安装canvas
npm install tesseract.js@5.0.4 canvas@2.11.2

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// WordProcess.class.js

const fs = require("fs");
const path = require("path");
const { createWorker } = require("tesseract.js");
const { createCanvas, loadImage } = require("canvas");

/**
* 图片文字处理类
*/
module.exports = class WordProcess {
resultFormat = /[\r\n\s]/g;
worker;

/**
* 初始化
* @param {String} modelCachePath tesseract模型缓存路径
* @param {String} langs 支持的语言包,默认为chi_sim+eng,表示中文简体和英文
*/
init(modelCachePath, langs) {
modelCachePath = modelCachePath || path.resolve(__dirname, "./lang");
langs = langs || "chi_sim+eng";

return new Promise((resolve, reject) => {
createWorker(langs, 1, {
cachePath: path.resolve(__dirname, modelCachePath),
})
.then((worker) => {
this.worker = worker;
resolve(this);
})
.catch((err) => {
reject(err);
});
});
}

/**
* 图片文字识别
* @param {string|Buffer} imgPath 图片地址
* @param {Boolean} format 是否去掉换行空格等符号
* @returns {Promise<string>}
*/
async ocr(imgPath, format = false) {
let res = await this.worker.recognize(imgPath);
let {
data: { text },
} = res;
if (format) text = text.replace(this.resultFormat, "");
return text;
}

/**
* 图片文字位置搜索,如果找到则返回文字在图片中的绝对坐标
* @param {string} str 要搜索位置的文字
* @param {string} imgPath 被搜索的图片
* @param {number} x 搜索起始坐标x
* @param {number} y 搜索起始坐标y
* @param {number} width 搜索宽度
* @param {number} height 搜索高度
* @param {[string, string]} colorRange 图片颜色过滤,这个范围外的颜色会被替换为白色
* @returns {Promise<{x: number, y: number}>} 绝对坐标点
*/
async findStr(
str,
imgPath,
x = 0,
y = 0,
width,
height,
colorRange = ["000000", "9f2e3f"]
) {
// 读取图片
let image = await loadImage(imgPath);

width = width || image.width;
height = height || image.height;

// 截取图片
let canvas = createCanvas(image.width, image.height);
let ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0);
let imageData = ctx.getImageData(x, y, width, height);
let croppedCanvas = createCanvas(width, height);
let croppedCtx = croppedCanvas.getContext("2d");
croppedCtx.putImageData(imageData, 0, 0);
// 过滤图片颜色
let imageData2 = croppedCtx.getImageData(0, 0, width, height);
let data = imageData2.data;
let colorRangeMin = colorRange[0]
.match(/\w{2}/g)
.map((v) => parseInt(v, 16)),
colorRangeMax = colorRange[1].match(/\w{2}/g).map((v) => parseInt(v, 16));
for (let i = 0; i < data.length; i += 4) {
let red = data[i];
let green = data[i + 1];
let blue = data[i + 2];
if (
red >= colorRangeMin[0] &&
red <= colorRangeMax[0] &&
green >= colorRangeMin[1] &&
green <= colorRangeMax[1] &&
blue >= colorRangeMin[2] &&
blue <= colorRangeMax[2]
)
continue;
data[i] = 255;
data[i + 1] = 255;
data[i + 2] = 255;
}
croppedCtx.putImageData(imageData2, 0, 0);

// 存储过滤了颜色后的图片
let buffer = croppedCanvas.toBuffer("image/png");
const tempImgPath = path.resolve(__dirname, "./temp.png");
fs.writeFileSync(tempImgPath, buffer);

// 文字识别
let res = await this.worker.recognize(tempImgPath);
let {
data: { lines },
} = res;

// 删除图片
fs.unlinkSync(tempImgPath);

// 搜索行
let line = lines.find((line, index) => {
return line.text.replace(this.resultFormat, "").indexOf(str) > -1;
});

if (!line) {
return { x: 0, y: 0 };
}

// 搜索列
let word = line.words.find((word, index) => {
return word.text.replace(this.resultFormat, "").indexOf(str[0]) > -1;
});
if (!word) {
return { x: 0, y: 0 };
}
let point = {
x: x + word.bbox.x0,
y: y + word.bbox.y0,
};
return point;
}
};

测试如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// test.js

const WordProcess = require("./WordProcess.class.js");

// 测试文字识别
const wp = new WordProcess();
wp.init()
.then(async (ins) => {
let imgPath = path.resolve(__dirname, "./test.png");

// 测试文字识别
let text = await ins.ocr(imgPath);
console.log(text);

// 测试文字位置搜索
let point = await ins.findStr("av", imgPath);
console.log(point);
})
.catch((err) => {
console.log(err);
});
  • 标题: nodejs项目使用tesseract的文字识别功能
  • 作者: 木头的喵喵拖孩
  • 创建于: 2025-01-03 14:39:18
  • 更新于: 2025-01-03 16:35:50
  • 链接: https://blog.xx-xx.top/2025/01/03/nodejs项目使用tesseract的文字识别功能/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
此页目录
nodejs项目使用tesseract的文字识别功能