You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用OpenCV去除图片黑边以提升OCR识别准确率

问题原因

你遇到的字符误删问题,是floodFill的默认填充逻辑导致的:当边缘字符紧贴黑边、和边角填充起始点的灰度差符合填充阈值时,会被判定为同一个连通域,一起被填充为白色,相当于被误删。
另外你原代码里还有两处笔误,会导致处理逻辑无效:

  • cv2.resize(image,(416,416)) 没有赋值给变量,resize操作不会修改原image对象,实际没有生效
  • 形态学操作直接传入(3,3)作为核不符合参数要求,需要用numpy生成uint8类型的结构元素

修复方案

给floodFill加上严格的阈值限制和掩码,或者改用轮廓裁剪的方案完全规避误伤问题,修改后的代码如下:

import cv2
import numpy as np
from matplotlib import pyplot as plt

image = cv2.imread(filename)
# 修正resize未赋值的问题
image = cv2.resize(image,(416,416))
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
img_lp = cv2.resize(gray, (333, 75))

# 二值化
_, img_binary_lp = cv2.threshold(img_lp, 200, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# 修正形态学操作的核定义
kernel = np.ones((3,3), np.uint8)
img_binary_lp = cv2.erode(img_binary_lp, kernel)
img_binary_lp = cv2.dilate(img_binary_lp, kernel)

# 优化版floodFill方案:加阈值和掩码限制,避免填充到字符
h, w = img_binary_lp.shape[:2]
# floodFill要求掩码尺寸比原图大2个像素
mask = np.zeros((h+2, w+2), np.uint8)
# 仅填充和边角点灰度差不超过1的区域,只会处理纯黑边,不会误伤字符
cv2.floodFill(img_binary_lp, mask, (0,0), 255, loDiff=1, upDiff=1)
cv2.floodFill(img_binary_lp, mask, (w-1, 0), 255, loDiff=1, upDiff=1)
cv2.floodFill(img_binary_lp, mask, (0, h-1), 255, loDiff=1, upDiff=1)
cv2.floodFill(img_binary_lp, mask, (w-1, h-1), 255, loDiff=1, upDiff=1)

# 极端场景替代方案:注释掉上面的floodFill部分,用轮廓裁剪彻底规避误伤
"""
# 提取所有深色(字符+黑边)区域的轮廓
contours, _ = cv2.findContours(255 - img_binary_lp, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 取面积最大的轮廓,即为车牌有效字符所在区域
max_contour = max(contours, key=cv2.contourArea)
x, y, w_crop, h_crop = cv2.boundingRect(max_contour)
# 裁剪时留2px边距避免切到字符
padding = 2
crop_lp = img_binary_lp[max(0, y-padding):min(h, y+h_crop+padding), max(0, x-padding):min(w, x+w_crop+padding)]
# 还原到固定尺寸
img_binary_lp = cv2.resize(crop_lp, (333, 75))
"""

LP_WIDTH = img_binary_lp.shape[0]
LP_HEIGHT = img_binary_lp.shape[1]

# Make borders white
img_binary_lp[0:3,:] = 255
img_binary_lp[:,0:3] = 255
img_binary_lp[72:75,:] = 255
img_binary_lp[:,330:333] = 255

#Estimations of character contours sizes of cropped license plates
dimensions = [LP_WIDTH/6,
                   LP_WIDTH/2,
                   LP_HEIGHT/10,
                   2*LP_HEIGHT/3]

plt.imshow(img_binary_lp, cmap='gray')

方案选择建议

  • 多数黑边和字符区分明显的场景,用优化后的floodFill方案即可,处理速度更快
  • 如果经常出现字符紧贴图片边缘的情况,直接用轮廓裁剪方案,稳定性更高

内容的提问来源于stack exchange,提问作者devansh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 01:54:04