我有一张非常嘈杂的图像,我必须对其执行 OCR。所附的片段是更大图像的一部分。我将如何以最佳方式预处理该图像?
我已经尝试使用大津二值化对图像进行预处理,使用各种滤波器和侵 eclipse 扩张来平滑图像。我还使用connectedComponentWithStats 来消除图像中的噪声。但这些都无助于处理污迹文本
编辑 - 该文本需要进行预处理才能执行 OCR
img = cv2.imread(file,0)
gaus = cv2.GaussianBlur(img,(5,5),0)
_, blackAndWhite = cv2.threshold(gaus, 127, 255, cv2.THRESH_BINARY_INV)
nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(blackAndWhite, None, None, None, 8, cv2.CV_32S)
sizes = stats[1:, -1]
img2 = np.zeros((labels.shape), np.uint8)
for i in range(0, nlabels - 1):
if sizes[i] >= 50:
img2[labels == i + 1] = 255
res = cv2.bitwise_not(img2)
(thresh, img_bin) = cv2.threshold(img, 128, 255,cv2.THRESH_BINARY| cv2.THRESH_OTSU)
img_bin = 255-img_bin
kernel_length = np.array(img).shape[1]//80
verticle_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, kernel_length))
hori_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (kernel_length, 1))
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
img_temp1 = cv2.erode(img_bin, verticle_kernel, iterations=3)
verticle_lines_img = cv2.dilate(img_temp1, verticle_kernel, iterations=3)
img_temp2 = cv2.erode(img_bin, hori_kernel, iterations=3)
horizontal_lines_img = cv2.dilate(img_temp2, hori_kernel, iterations=3)
alpha = 0.5
beta = 1.0 - alpha
img_final_bin = cv2.addWeighted(verticle_lines_img, alpha, horizontal_lines_img, beta, 0.0)
img_final_bin = cv2.erode(~img_final_bin, kernel, iterations=2)
(thresh, img_final_bin) = cv2.threshold(img_final_bin, 128,255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
最佳答案
这是消除噪音的方法
- 将图像转换为灰度和 Otsu 阈值
- 执行形态变换以平滑图像
- 查找轮廓并使用轮廓区域进行过滤
- 反转图像
转换为灰度后,我们通过Otsu的阈值得到二值图像
从这里我们创建一个内核并执行形态学开放以平滑图像。您可以尝试在此处使用不同的内核大小来消除更多噪音,但增加内核大小也会删除文本细节
接下来,我们找到轮廓并使用具有最大阈值区域的轮廓区域进行过滤以去除小颗粒。我们填充轮廓以有效去除噪声
最后我们反转图像以获得结果
import cv2
import numpy as np
image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=1)
cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area < 150:
cv2.drawContours(opening, [c], -1, (0,0,0), -1)
result = 255 - opening
cv2.imshow('thresh', thresh)
cv2.imshow('opening', opening)
cv2.imshow('result', result)
cv2.waitKey()
关于python - 如何预处理图像以去除噪声并提取Python文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57850107/