如何从埃及文字图像的每个单词中提取单个字符?
埃及文字自定义OCR:单词区分与单字符提取方案
核心思路:基于字符边界框的聚类分组
阿拉伯语(埃及方言)手写体的单词间间距通常大于单词内字符间距,可通过字符边界框的x坐标间距聚类区分单词,再对每个单词内的字符按顺序提取。
具体实现步骤
1. 计算字符间距阈值
遍历所有字符的boundingRect,计算相邻字符的x轴间距,取间距中位数的1.5倍作为单词分隔阈值(可根据实际数据调整系数):
# 计算相邻字符的间距 gap_threshold = 0 if len(cnts) > 1: gaps = [] for i in range(1, len(cnts)): prev_x, _, prev_w, _ = cv2.boundingRect(cnts[i-1]) curr_x, _, _, _ = cv2.boundingRect(cnts[i]) gaps.append(curr_x - (prev_x + prev_w)) # 取中位数的1.5倍作为分隔阈值 gap_threshold = np.median(gaps) * 1.5
2. 按阈值分组字符为单词
遍历字符边界框,当相邻字符间距超过阈值时,将之前的字符划分为一个单词:
words = [] current_word = [] for i, c in enumerate(cnts): x, y, w, h = cv2.boundingRect(c) if h > 16 and w > 1: # 过滤小噪声区域 current_word.append(c) # 判断是否需要结束当前单词 if i == len(cnts)-1: words.append(current_word) else: next_x, _, _, _ = cv2.boundingRect(cnts[i+1]) if (next_x - (x + w)) > gap_threshold: words.append(current_word) current_word = []
3. 提取并预处理单词内的单个字符
对每个单词内的字符按x坐标排序,预处理后适配模型输入尺寸(注意阿拉伯语从右到左的书写顺序,需反转字符列表):
processed_words = [] for word in words: # 按x坐标排序字符 sorted_chars = sorted(word, key=lambda x: cv2.boundingRect(x)[0]) word_chars = [] for c in sorted_chars: x, y, w, h = cv2.boundingRect(c) # 正确提取字符ROI(原代码此处x:x+h错误,应改为x:x+w) roi = gray[y:y+h, x:x+w] # 缩放并填充至目标尺寸,避免字符拉伸 scale = min(TARGET_WIDTH/w, TARGET_HEIGHT/h) new_w, new_h = int(w*scale), int(h*scale) resized_roi = cv2.resize(roi, (new_w, new_h), interpolation=cv2.INTER_AREA) # 居中填充到48x48 padded_roi = np.zeros((TARGET_HEIGHT, TARGET_WIDTH), dtype=np.uint8) x_pad, y_pad = (TARGET_WIDTH-new_w)//2, (TARGET_HEIGHT-new_h)//2 padded_roi[y_pad:y_pad+new_h, x_pad:x_pad+new_w] = resized_roi # 颜色反转(匹配训练时的白底黑字格式) padded_roi = cv2.bitwise_not(padded_roi) word_chars.append(padded_roi) # 反转字符顺序,适配阿拉伯语从右到左的阅读逻辑 word_chars.reverse() processed_words.append(word_chars)
4. 模型识别与结果拼接
加载训练好的模型,对预处理后的字符进行识别并拼接成单词:
# 加载模型 model = load_model('your_trained_model.h5') recognized_text = [] for word_chars in processed_words: word_text = "" for char_img in word_chars: # 适配模型输入格式 img_input = np.expand_dims(np.expand_dims(char_img, axis=-1), axis=0) / 255.0 pred = model.predict(img_input, verbose=0) char_idx = np.argmax(pred) word_text += chars[char_idx] recognized_text.append(word_text) # 打印最终识别结果 print("识别结果:", " ".join(recognized_text))
关键注意事项
- 边界框修正:原代码中
roi = image[y:y+h, x:x+h]存在错误,应改为x:x+w,避免提取错误区域导致字符变形。 - 方向适配:阿拉伯语为从右到左书写,单词内字符列表需反转后再识别,才能得到正确的单词顺序。
- 阈值调优:
gap_threshold的系数需根据你的数据集调整,避免单词拆分或合并错误。 - 预处理对齐:字符的归一化、尺寸调整、颜色反转必须与模型训练时的预处理逻辑完全一致,否则会大幅降低识别准确率。
内容的提问来源于stack exchange,提问作者Emad Uones
相关产品推荐
相关产品推荐

