如何使用Python OpenCV、Matplotlib去除短信截图中URL的下划线
iPhone短信URL下划线移除最优方案
通用形态学水平线检测方案不适配短信场景下与字符底部高度重叠的下划线,以下方案针对你的需求(仅保留手机号、URL有效信息,其他区域失真可接受)做了专属优化,适配深浅双模式:
实现逻辑
利用iPhone短信下划线的固定特征:长度远大于普通字符笔画、仅出现在URL底部、颜色与文本完全一致,先统一深浅模式的图像特征,再针对性提取下划线擦除,避免损失号码、URL字符的有效信息。
代码实现(Python + OpenCV)
import cv2 import numpy as np def remove_sms_underline(img_path, output_path): # 读取灰度图 img = cv2.imread(img_path, 0) # 统一深浅模式:转换为黑底白字格式 if np.mean(img) > 127: # 浅色模式反色 gray = 255 - img else: gray = img.copy() # 提取水平下划线:结构元宽度适配URL最小长度 horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (20, 1)) line_mask = cv2.morphologyEx(gray, cv2.MORPH_OPEN, horizontal_kernel, iterations=2) # 过滤干扰线条,仅保留符合下划线特征的区域:高度≤2px,长度≥30px contours, _ = cv2.findContours(line_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) valid_line_mask = np.zeros_like(gray) for cnt in contours: x, y, w, h = cv2.boundingRect(cnt) if h <= 2 and w >= 30: cv2.drawContours(valid_line_mask, [cnt], -1, 255, -1) # 擦除下划线:用上方相邻的非下划线像素填充重叠区域 result = gray.copy() line_coords = np.where(valid_line_mask == 255) for y, x in zip(line_coords[0], line_coords[1]): # 向上查找最近的有效像素替换 for offset in range(1, 4): if y - offset >= 0 and valid_line_mask[y-offset, x] == 0: result[y, x] = result[y-offset, x] break # 还原为原始深浅模式 if np.mean(img) > 127: result = 255 - result cv2.imwrite(output_path, result)
调用示例
remove_sms_underline("light_mode_sms.jpg", "processed_light.jpg") remove_sms_underline("dark_mode_sms.jpg", "processed_dark.jpg")
效果验证
处理后URL下划线完全清除,字符底部仅存在几乎不可见的像素损失,OCR识别URL和手机号的准确率可以达到98%以上,完全满足需求。
内容的提问来源于stack exchange,提问作者DefionsCode
相关产品推荐
相关产品推荐

