预处理图像以提取文本并消除噪点

时间:2019-09-09 08:12:21

标签: python image opencv image-processing computer-vision

[![在此处输入图像描述] [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)

1 个答案:

答案 0 :(得分:2)

这是一种消除噪音的方法

  • 将图像转换为灰度并达到Otsu的阈值
  • 执行形态转换以使图像平滑
  • 查找轮廓并使用轮廓区域进行过滤
  • 反转图像

转换为灰度后,我们以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()