Toughen1 commited on
Commit
923ae64
·
verified ·
1 Parent(s): 4f0787e

语言支持

Browse files
Files changed (1) hide show
  1. app.py +109 -8
app.py CHANGED
@@ -65,6 +65,15 @@ FASTTEXT_TO_PADDLE = {
65
  "ja": "japan", # 日语
66
  }
67
 
 
 
 
 
 
 
 
 
 
68
  CONCURRENCY_LIMIT = 8
69
 
70
 
@@ -126,10 +135,14 @@ def create_model(lang):
126
  return PaddleOCR(lang=lang, use_angle_cls=True, use_gpu=False)
127
 
128
 
 
 
129
  model_managers = {}
130
  for lang, config in LANG_CONFIG.items():
 
131
  model_manager = PaddleOCRModelManager(config["num_workers"], functools.partial(create_model, lang=lang))
132
  model_managers[lang] = model_manager
 
133
 
134
 
135
  def close_model_managers():
@@ -141,14 +154,43 @@ def close_model_managers():
141
  atexit.register(close_model_managers)
142
 
143
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  def detect_language_with_fasttext(text):
145
  """使用fasttext检测语言"""
146
  if not text or not text.strip():
147
  return "en"
148
 
149
  if lang_model is None:
150
- # 如果fasttext模型加载失败,使用默认语言
151
- return "en"
152
 
153
  try:
154
  # 预处理文本,保留一定长度
@@ -159,17 +201,58 @@ def detect_language_with_fasttext(text):
159
  lang_code = predictions[0][0].replace('__label__', '')
160
 
161
  # 映射到PaddleOCR支持的语言
162
- return FASTTEXT_TO_PADDLE.get(lang_code, "en")
 
 
 
 
 
 
163
  except Exception as e:
164
  print(f"语言检测错误: {e}")
165
- return "en" # 出错时默认使用英文
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
 
167
 
168
  def auto_detect_language(image_path):
169
  """使用多模型投票的方式检测语言"""
170
- # 尝试不同语言的模型
171
- languages_to_try = ["en", "ch"] # 先尝试英文,然后是中文
172
  results = {}
 
173
 
174
  for lang in languages_to_try:
175
  try:
@@ -178,6 +261,8 @@ def auto_detect_language(image_path):
178
  if result:
179
  # 提取所有文本
180
  all_text = " ".join([line[1][0] for line in result])
 
 
181
  if all_text.strip():
182
  # 使用fasttext检测语言
183
  detected = detect_language_with_fasttext(all_text)
@@ -186,9 +271,17 @@ def auto_detect_language(image_path):
186
  print(f"OCR处理错误 ({lang}): {e}")
187
  continue
188
 
189
- # 如果没有检测结果,默认使用英文
 
 
 
 
 
 
190
  if not results:
191
- return "en"
 
 
192
 
193
  # 返回得票最多的语言
194
  return max(results.items(), key=lambda x: x[1])[0]
@@ -234,11 +327,19 @@ def inference(img, return_text_only=True):
234
 
235
  # 自动检测语言
236
  lang = auto_detect_language(img_path)
 
237
 
238
  # 使用检测到的语言进行OCR
239
  ocr = model_managers[lang]
240
  result = ocr.infer(img_path, cls=True)[0]
241
 
 
 
 
 
 
 
 
242
  # 提取文本和位置信息
243
  boxes = [line[0] for line in result]
244
  txts = [line[1][0] for line in result]
 
65
  "ja": "japan", # 日语
66
  }
67
 
68
+ # 语言特征检测 - 用于备用语言检测
69
+ LANG_FEATURES = {
70
+ "ch": set("的一是不了人我在有他这为之大来以个中上们"),
71
+ "en": set("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
72
+ "fr": set("àâäæçéèêëîïôœùûüÿÀÂÄÆÇÉÈÊËÎÏÔŒÙÛÜŸ"),
73
+ "german": set("äöüßÄÖÜ"),
74
+ "japan": set("あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんアイウエオカキクケコサシスセソタチツテト")
75
+ }
76
+
77
  CONCURRENCY_LIMIT = 8
78
 
79
 
 
135
  return PaddleOCR(lang=lang, use_angle_cls=True, use_gpu=False)
136
 
137
 
138
+ # 预先加载所有语言的模型
139
+ print("正在初始化多语言OCR模型...")
140
  model_managers = {}
141
  for lang, config in LANG_CONFIG.items():
142
+ print(f"加载 {LANG_MAP.get(lang, lang)} 模型...")
143
  model_manager = PaddleOCRModelManager(config["num_workers"], functools.partial(create_model, lang=lang))
144
  model_managers[lang] = model_manager
145
+ print("所有OCR模型加载完成")
146
 
147
 
148
  def close_model_managers():
 
154
  atexit.register(close_model_managers)
155
 
156
 
157
+ def detect_language_by_features(text):
158
+ """基于特征字符集检测语言"""
159
+ if not text:
160
+ return "en"
161
+
162
+ # 计算每种语言的特征字符出现比例
163
+ lang_scores = {}
164
+ for lang, char_set in LANG_FEATURES.items():
165
+ if not char_set:
166
+ continue
167
+
168
+ # 计算文本中该语言特征字符的数量
169
+ count = sum(1 for char in text if char in char_set)
170
+ if count > 0:
171
+ lang_scores[lang] = count / len(text)
172
+
173
+ # 特殊处理韩语(通过Unicode范围检测)
174
+ korean_count = sum(1 for char in text if '\uac00' <= char <= '\ud7a3')
175
+ if korean_count > 0:
176
+ lang_scores["korean"] = korean_count / len(text)
177
+
178
+ # 如果没有检测到任何语言特征,默认为英语
179
+ if not lang_scores:
180
+ return "en"
181
+
182
+ # 返回特征比例最高的语言
183
+ return max(lang_scores.items(), key=lambda x: x[1])[0]
184
+
185
+
186
  def detect_language_with_fasttext(text):
187
  """使用fasttext检测语言"""
188
  if not text or not text.strip():
189
  return "en"
190
 
191
  if lang_model is None:
192
+ # 如果fasttext模型加载失败,使用基于特征的检测
193
+ return detect_language_by_features(text)
194
 
195
  try:
196
  # 预处理文本,保留一定长度
 
201
  lang_code = predictions[0][0].replace('__label__', '')
202
 
203
  # 映射到PaddleOCR支持的语言
204
+ paddle_lang = FASTTEXT_TO_PADDLE.get(lang_code, None)
205
+
206
+ # 如果无法映射,使用基于特征的检测作为备用
207
+ if paddle_lang is None:
208
+ return detect_language_by_features(text)
209
+
210
+ return paddle_lang
211
  except Exception as e:
212
  print(f"语言检测错误: {e}")
213
+ # 出错时使用基于特征的检测作为备用
214
+ return detect_language_by_features(text)
215
+
216
+
217
+ def try_all_languages(image_path):
218
+ """尝试所有语言的OCR,返回最佳结果"""
219
+ best_result = None
220
+ best_lang = "en"
221
+ max_text_length = 0
222
+
223
+ # 尝试所有语言
224
+ for lang in LANG_CONFIG.keys():
225
+ try:
226
+ ocr = model_managers[lang]
227
+ result = ocr.infer(image_path, cls=True)[0]
228
+
229
+ if result:
230
+ # 提取所有文本
231
+ all_text = " ".join([line[1][0] for line in result])
232
+ text_length = len(all_text.strip())
233
+
234
+ # 如果这个语言提取的文本更多,认为它更可能是正确的语言
235
+ if text_length > max_text_length:
236
+ max_text_length = text_length
237
+ best_result = result
238
+ best_lang = lang
239
+
240
+ # 如果是中文且提取了足够多的文本,直接返回
241
+ if lang == "ch" and text_length > 10:
242
+ return result, lang
243
+ except Exception as e:
244
+ print(f"OCR处理错误 ({lang}): {e}")
245
+ continue
246
+
247
+ return best_result, best_lang
248
 
249
 
250
  def auto_detect_language(image_path):
251
  """使用多模型投票的方式检测语言"""
252
+ # 先尝试中文和英文模型
253
+ languages_to_try = ["ch", "en"]
254
  results = {}
255
+ detected_texts = {}
256
 
257
  for lang in languages_to_try:
258
  try:
 
261
  if result:
262
  # 提取所有文本
263
  all_text = " ".join([line[1][0] for line in result])
264
+ detected_texts[lang] = all_text
265
+
266
  if all_text.strip():
267
  # 使用fasttext检测语言
268
  detected = detect_language_with_fasttext(all_text)
 
271
  print(f"OCR处理错误 ({lang}): {e}")
272
  continue
273
 
274
+ # 检查中文结果是否包含足够的中文字符
275
+ if "ch" in detected_texts:
276
+ chinese_chars = sum(1 for char in detected_texts["ch"] if '\u4e00' <= char <= '\u9fff')
277
+ if chinese_chars > 5: # 如果有超过5个中文字符
278
+ return "ch"
279
+
280
+ # 如果没有检测结果或者结果不可靠,尝试所有语言
281
  if not results:
282
+ print("无法可靠检测语言,尝试所有语言...")
283
+ _, best_lang = try_all_languages(image_path)
284
+ return best_lang
285
 
286
  # 返回得票最多的语言
287
  return max(results.items(), key=lambda x: x[1])[0]
 
327
 
328
  # 自动检测语言
329
  lang = auto_detect_language(img_path)
330
+ print(f"检测到的语言: {LANG_MAP.get(lang, lang)}")
331
 
332
  # 使用检测到的语言进行OCR
333
  ocr = model_managers[lang]
334
  result = ocr.infer(img_path, cls=True)[0]
335
 
336
+ # 如果结果为空或很少,尝试所有语言
337
+ all_text = " ".join([line[1][0] for line in result])
338
+ if len(all_text.strip()) < 5:
339
+ print("识别结果太少,尝试所有语言...")
340
+ result, lang = try_all_languages(img_path)
341
+ print(f"最佳语言: {LANG_MAP.get(lang, lang)}")
342
+
343
  # 提取文本和位置信息
344
  boxes = [line[0] for line in result]
345
  txts = [line[1][0] for line in result]