[![在此处输入图像描述] [1]] [1]我有一个非常嘈杂的图像,必须对其执行OCR。附加的摘录是较大图像的一部分。我将如何以最佳方式预处理此图像?
我已经尝试使用Otsu Binarization预处理图像,使用各种滤镜和Erosion-Dilation平滑图像。我还使用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)
答案 0 :(得分:2)
这是一种消除噪音的方法
转换为灰度后,我们以Otsu的阈值获取二进制图像
[![在此处输入图片描述] [1]] [1]
从这里我们创建一个内核,并执行形态学开放以平滑图像。您可以在此处尝试使用不同的内核大小来消除更多的噪音,但是增加内核大小也会删除文本细节
[![在此处输入图片描述] [2]] [2]
接下来,我们找到轮廓并使用轮廓区域(具有最大阈值区域)进行过滤以除去小颗粒。我们填充轮廓以有效去除噪音
[![在此处输入图片描述] [3]] [3]
最后,我们反转图像以获得结果
[![在此处输入图片描述] [4]] [4]
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()