Исходное изображение
Ниже приведены мои попытки и результаты.
Предварительная обработка: перед проецированием выполняется более мощная предварительная обработка изображения для уменьшения шума, в том числе:
Медианная фильтрация или двусторонняя фильтрация для сглаживания изображения и уменьшения шум.
Используйте морфологические операции, чтобы улучшить текстовую область и удалить небольшие точки шума.
Обнаружение краев Собела или обнаружение краев Кэнни может помочь выделить края текста.
Обработка слипания символов: используйте преобразование расстояния и алгоритм Watershed для сегментации слипающихся символов.
Код: Выделить всё
# 读取图像
image_path = "./result/cropped_2.jpg"
image = cv2.imread(image_path)
# 转换为灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 1. 中值滤波去噪声
gray = cv2.medianBlur(gray, 3)
# 2. 使用Sobel边缘检测增强文字边缘
sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)
sobel = np.sqrt(sobelx**2 + sobely**2)
sobel = cv2.convertScaleAbs(sobel)
cv2.imwrite('slobe.jpg',sobel)
# 3. 使用Otsu阈值进行二值化
_, binary = cv2.threshold(sobel, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 4. 使用形态学操作(膨胀+腐蚀)去除噪声
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
morph = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)
# 5. 使用距离变换分离粘连的字符
dist_transform = cv2.distanceTransform(morph, cv2.DIST_L2, 5)
_, sure_fg = cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0)
# 6. 使用Watershed算法分割粘连字符
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(morph, sure_fg)
# 计算轮廓和标记
_, markers = cv2.connectedComponents(sure_fg)
markers = markers + 1
markers[unknown == 255] = 0
# 应用Watershed算法
markers = cv2.watershed(image, markers)
image[markers == -1] = [255, 0, 0]
cv2.imwrite('watershed.jpg',image)
# 7. 垂直投影法用于字符分割
h_projection = np.sum(morph, axis=1)
# 显示水平投影
plt.figure(figsize=(10, 6))
plt.plot(h_projection)
plt.title("Horizontal Projection After Improvement")
plt.show()
# 对每一行进行字符分割(垂直投影法)
lines = []
thresh = np.max(h_projection) * 0.2
in_line = False
for i in range(len(h_projection)):
if h_projection[i] > thresh and not in_line:
start = i
in_line = True
elif h_projection[i] thresh_v and not in_char:
x_start = j
in_char = True
elif v_projection[j]
Подробнее здесь: [url]https://stackoverflow.com/questions/79016858/split-each-character-from-multiline-text[/url]