如何利用已获取的水平投影分割手写文本行并保存?
基于水平投影分割手写单行文本并保存
我已经成功获取手写图像的水平投影(Python实现代码如下),希望通过该水平投影分割并保存单行文本文字。我知晓其他实现方法,但希望基于当前获取的水平投影完成。关注投影值从大于0开始到再次变为0的像素区间,投影图中的峰值对应文本区域,需分割原图像中的这些单行文本区域并保存。
原水平投影获取代码
import numpy as np import cv2 def getHorizontalProjectionProfile(image): # 将黑色区域转为1,白色区域转为0 image[image == 0] = 1 image[image == 255] = 0 # 计算每行的像素和,得到水平投影 horizontal_projection = np.sum(image, axis=1) return (horizontal_projection, image) # 调用函数获取水平投影(binary为二值化手写图像) horizontal_projection, processed_img = getHorizontalProjectionProfile(binary.copy()) # 绘制投影可视化图 m = np.max(horizontal_projection) w = 500 result = np.zeros((horizontal_projection.shape[0], 500)) for row in range(processed_img.shape[0]): cv2.line(result, (0, row), (int(horizontal_projection[row]*w/m), row), (255,255,255), 1) cv2.imshow('Horizontal Projection', result) cv2.waitKey(0) cv2.destroyAllWindows()
基于水平投影的文本行分割与保存
在上述代码基础上,添加以下逻辑提取并保存文本行:
# 分析水平投影,定位文本行的起止行号 text_rows = [] start_row = None for row_idx, proj_val in enumerate(horizontal_projection): # 投影值大于0,判定为文本行起始或持续 if proj_val > 0: if start_row is None: start_row = row_idx else: # 投影值为0,且已记录起始行,判定为文本行结束 if start_row is not None: text_rows.append((start_row, row_idx - 1)) start_row = None # 处理图像末尾未闭合的文本行 if start_row is not None: text_rows.append((start_row, len(horizontal_projection) - 1)) # 创建保存目录并分割保存文本行 save_dir = "handwritten_lines/" import os os.makedirs(save_dir, exist_ok=True) for idx, (start, end) in enumerate(text_rows): # 从原二值化图像中截取文本行区域 line_img = binary[start:end+1, :] # 保存图像 cv2.imwrite(f"{save_dir}/line_{idx+1}.png", line_img) # 可选:实时查看分割结果 cv2.imshow(f"Line {idx+1}", line_img) cv2.waitKey(0) cv2.destroyAllWindows()
关键说明
- 投影分析逻辑:通过遍历投影数组,捕捉投影值从0到非0、再从非0到0的节点,精准定位每个文本行的垂直区间。
- 噪声处理:如果图像存在零星噪声导致投影出现无效非0值,可先对投影数组做平滑处理(比如用
np.convolve执行均值滤波),避免分割出无效小区域。
内容的提问来源于stack exchange,提问作者TheNeanderthal
相关产品推荐
相关产品推荐

