为何中值滤波会导致数独OCR预处理结果变差?
数独OCR预处理:中值滤波效果反降的原因分析
我正在开发一款数独OCR系统,目标是获取清晰的黑白分割图像。当前预处理流程为:灰度化→中值滤波→Otsu二值化,但实际测试发现去掉中值滤波后,处理结果反而更好。结合图像表现和代码实现,原因主要有以下几点:
1. 中值滤波的应用逻辑错误
你的代码直接在彩色图像上对每个3x3邻域计算灰度值,再用中值替换原像素的RGB通道。正确的预处理逻辑应该是:先完成全图灰度化,得到单通道灰度图后,再对灰度图执行中值滤波。你当前的做法相当于在每个邻域重复计算灰度,不仅效率低下,还会将邻域内的亮暗像素混合,直接破坏数独数字原本清晰的边缘——数字边缘是高对比度的关键特征,中值滤波会把边缘的明暗过渡抹平,导致后续Otsu二值化无法准确区分数字与背景。
2. 原图无有效噪声,中值滤波反而破坏细节
中值滤波的核心作用是去除椒盐噪声(随机出现的亮/暗孤立噪点),但你的原图几乎没有这类噪点:数字笔画清晰,网格边缘锐利,背景干净。这种情况下,中值滤波不仅没有降噪价值,反而会平滑掉数字笔画的棱角和细微边缘,降低数字与背景的对比度,最终让Otsu分割丢失关键细节,效果自然不如直接灰度化+Otsu的组合。
3. 代码实现的两处潜在问题
- 灰度计算精度丢失:你用浮点运算
(0.3 * r) + (0.59 * g) + (0.11 * b)计算灰度后直接赋值给Uint8,会导致小数部分被截断(比如123.9会变成123),长期来看会影响灰度化的准确性,建议改用整数运算避免截断:(30*r + 59*g + 11*b)/100。 - 排序函数可能出错:
qsort的cmpfunc如果未正确处理Uint8类型,会导致排序逻辑混乱——比如按int比较时,Uint8值超过127会被识别为负数,进而取到错误的中值。
改进建议
- 调整预处理流程:先完成全图灰度化得到单通道灰度图,仅当图像存在明显椒盐噪声时再使用中值滤波;
- 若需保留滤波,尝试缩小窗口尺寸(如2x2)或改用双边滤波(边缘保留型滤波),避免破坏数字边缘;
- 修复灰度计算的精度问题,确保
cmpfunc正确实现Uint8的比较逻辑。
内容的提问来源于stack exchange,提问作者bede walthew
相关产品推荐
相关产品推荐

