如何用OpenCV区分粗体文本与手写笔迹并移除粗体文本?
移除图片中粗体文本、保留手写笔迹的解决方案
你之前用的1x1腐蚀核完全不起作用——因为1x1的核在腐蚀操作中只会取当前像素本身的值,根本不会改变图像内容,自然无法移除粗体文本。结合你的需求(区分印刷粗体和手写笔迹),可以通过以下两种针对性方法解决:
方法一:利用形态学开运算(针对字体笔画特征差异)
粗体印刷体的笔画通常规整且横向/纵向宽度一致,而手写笔迹线条细、形态不规则。可以用横向矩形核的开运算(先腐蚀后膨胀),精准去除粗体,同时保留手写笔迹:
import cv2 import numpy as np # 读取图片并转为灰度图 img = cv2.imread('your_image.png', 0) # 二值化处理(根据实际背景调整阈值,这里假设背景为白色,文字为黑色) _, binary_img = cv2.threshold(img, 240, 255, cv2.THRESH_BINARY_INV) # 创建横向矩形核:针对粗体印刷体的横向宽度,可根据实际调整尺寸 kernel = np.ones((1, 5), np.uint8) # 开运算:先腐蚀去除粗体,再膨胀恢复手写笔迹的线条 cleaned_img = cv2.morphologyEx(binary_img, cv2.MORPH_OPEN, kernel) # 还原为原图像的色彩模式(白底黑字) cleaned_img = cv2.bitwise_not(cleaned_img) cv2.imwrite('result.png', cleaned_img)
调整技巧:
- 如果粗体是纵向排版,把核改为
np.ones((5, 1), np.uint8) - 核的尺寸可根据粗体笔画宽度微调(比如粗体更宽就把5改成7)
方法二:轮廓分析筛选(根据轮廓特征区分)
印刷粗体的轮廓面积大、长宽比规整,手写笔迹的轮廓面积小、形态不规则。通过轮廓筛选可以精准保留手写部分:
import cv2 import numpy as np img = cv2.imread('your_image.png', 0) _, binary_img = cv2.threshold(img, 240, 255, cv2.THRESH_BINARY_INV) # 提取所有外部轮廓 contours, _ = cv2.findContours(binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 创建空白画布用于绘制结果 result = np.zeros_like(binary_img) # 遍历轮廓,筛选手写特征的轮廓 for cnt in contours: area = cv2.contourArea(cnt) x, y, w, h = cv2.boundingRect(cnt) aspect_ratio = w / h # 根据实际情况调整阈值:比如面积小于100、长宽比偏离常规印刷体范围 if area < 100 or (aspect_ratio < 0.5 or aspect_ratio > 2): cv2.drawContours(result, [cnt], 0, 255, -1) # 还原色彩模式并保存 result = cv2.bitwise_not(result) cv2.imwrite('result.png', result)
调整技巧:
- 根据图片中粗体和手写的实际大小,修改
area的阈值 - 印刷体的长宽比通常在0.5-2之间(比如英文单词的字母),可根据实际场景调整范围
内容的提问来源于stack exchange,提问作者AScientist9797
相关产品推荐
相关产品推荐

