手写数字图像经轮廓提取与缩放后识别错误的问题咨询
变形原因
- 核心问题是未保持宽高比的强制拉伸:你的代码直接调用
cv.resize(digit, (18,18)),不考虑裁剪得到的数字区域原始宽高比例,直接拉伸为正方形。手写数字5通常为竖长形态,强制拉成正方形后横向会被过度拓宽,笔画特征变形后和数字3重合,导致误识别。 - 次要问题:二值图像使用默认插值算法缩放,会造成笔画边缘模糊、形态畸变,进一步干扰模型判断。
- 隐藏问题:直接对缩放后的图像四周补边,没有做居中校正,如果原始数字在外接矩形中存在偏移,补边后会出现整体位置偏移,也会影响识别准确率。
修复方案
替换原有缩放、填充逻辑,先将裁剪到的数字区域等比例缩放后填充为正方形,再做后续处理,参考修改代码如下:
for c in contours: x,y,w,h = cv.boundingRect(c) # 可额外增加宽高比过滤,排除异常噪点轮廓 if w*h >= 130 and 0.2 < w/h < 5: cv.rectangle(image, (x,y), (x+w, y+h), color=(0, 255, 0), thickness=2) digit = thresh[y:y+h, x:x+w] # 新增:保持宽高比缩放,避免拉伸变形 origin_h, origin_w = digit.shape max_side = max(origin_h, origin_w) # 创建正方形黑底画布,将原始数字放在画布中央 square_canvas = np.zeros((max_side, max_side), dtype=np.uint8) offset_x = (max_side - origin_w) // 2 offset_y = (max_side - origin_h) // 2 square_canvas[offset_y:offset_y+origin_h, offset_x:offset_x+origin_w] = digit # 缩放时使用最近邻插值,适配二值图像保留笔画特征 resized_digit = cv.resize(square_canvas, (18,18), interpolation=cv.INTER_NEAREST) padded_digit = np.pad(resized_digit, ((5,5),(5,5)), "constant", constant_values=0) # 后续预测逻辑不变 plt.imshow(padded_digit, cmap="gray") plt.show() xdigit = padded_digit.reshape(1,784) prediction = neigh.predict(xdigit) print("prediction = ",prediction[0])
内容的提问来源于stack exchange,提问作者sunny
相关产品推荐
相关产品推荐

