我正在使用Python中的OpenCV进行图像处理和Tesseract OCR进行字符识别,开发一个车牌识别系统。我已经编写了一个函数来处理车牌图像并从中提取文本,但在一致检测大字体和小字体字符方面遇到了问题。该函数旨在锐化图像、增加对比度,并在使用Tesseract OCR之前应用各种预处理步骤。
@staticmethod
def process_license_plate(frame, x1, y1, x2, y2):
"""
使用增强的OCR从帧中提取并处理车牌区域。
参数:
- frame (numpy.ndarray): 包含车牌的图像或视频帧。
- x1, y1, x2, y2 (int): 车牌边界框的坐标。
返回:
- str: 识别出的车牌文本。
"""
# 步骤1:裁剪车牌区域
license_plate_area = frame[y1:y2, x1:x2]
# 步骤2:使用核函数锐化车牌区域
sharpening_kernel = np.array([[-1, -1, -1], [-1, 9, -1], [-1, -1, -1]])
sharpened_license_plate = cv2.filter2D(license_plate_area, -1, sharpening_kernel)
# 步骤3:使用CLAHE增加对比度
lab = cv2.cvtColor(sharpened_license_plate, cv2.COLOR_BGR2LAB)
l, a, b = cv2.split(lab)
clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8))
limg = cv2.merge([clahe.apply(l), a, b])
enhanced_license_plate = cv2.cvtColor(limg, cv2.COLOR_LAB2BGR)
# 步骤4:为OCR预处理 - 灰度转换、高斯模糊和自适应阈值
grayscale_license_plate = cv2.cvtColor(enhanced_license_plate, cv2.COLOR_BGR2GRAY)
blurred_license_plate = cv2.GaussianBlur(grayscale_license_plate, (3, 3), 0)
_, thresholded_license_plate = cv2.threshold(blurred_license_plate, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 步骤5:形态学操作清理图像
morph_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
opened_license_plate = cv2.morphologyEx(thresholded_license_plate, cv2.MORPH_OPEN, morph_kernel, iterations=1)
inverted_license_plate = cv2.bitwise_not(opened_license_plate)
# 步骤6 1/2:使用OCR提取文本
license_plate_text = pytesseract.image_to_string(
inverted_license_plate, lang='eng',
config='--psm 6 -c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
)
return license_plate_text.strip()
我尝试通过使用车牌高度比例作为参考来隔离较大的字符。然而,正如预期的那样,这种方法并未成功。
# 步骤6:过滤掉较小的元素,保留较大的字符(可选)
contours, _ = cv2.findContours(inverted_license_plate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
filtered_license_plate = np.zeros_like(inverted_license_plate)
# 定义轮廓面积的阈值(例如,车牌区域的90%)
threshold_area = 0.9 * license_plate_area.shape[0] * license_plate_area.shape[1] # 调试值
for contour in contours:
if cv2.contourArea(contour) > threshold_area:
cv2.drawContours(filtered_license_plate, [contour], -1, (255, 255, 255), thickness=cv2.FILLED)
这是应用过滤器后的最终结果:
这是未应用过滤器的结果: