简体   繁体   English

如何预处理图像以去除噪声并提取文本 Python?

[英]How to preprocess an image to remove noise and extract text Python?

在此处输入图像描述

I have a really noisy image that I have to perform OCR on.我有一个非常嘈杂的图像,我必须对其执行 OCR。 The snippet attached is part of a bigger image.附加的片段是更大图像的一部分。 How would I go about pre-processing this image in the most optimal way?我将如何以最佳方式预处理此图像?

I have already tried pre-processing the image using Otsu Binarization, smoothing the image using various filters and Erosion-Dilation.我已经尝试使用 Otsu Binarization 对图像进行预处理,使用各种过滤器和 Erosion-Dilation 对图像进行平滑处理。 I've also used connectedComponentWithStats to remove the noise in the image.我还使用了 connectedComponentWithStats 来消除图像中的噪点。 But none of this helps with the processing of the smudged text但这对处理污迹文本没有任何帮助

Edit - This text needs to be pre-processed in order to perform OCR编辑 - 此文本需要进行预处理才能执行 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)

Here's an approach to remove the noise这是一种消除噪音的方法

  • Convert image to grayscale and Otsu's threshold将图像转换为灰度和 Otsu 的阈值
  • Perform morphological transformations to smooth image执行形态变换以平滑图像
  • Find contours and filter using contour area使用轮廓区域查找轮廓和过滤
  • Invert image反转图像

After converting to grayscale, we Otsu's threshold to obtain a binary image转换为灰度后,我们用Otsu的阈值得到二值图像

在此处输入图像描述

From here we create a kernel and perform morphological opening to smooth the image.从这里我们创建一个内核并执行形态学打开以平滑图像。 You could try using different kernels sizes here to remove more noise but increasing the kernel size will also remove text detail您可以尝试在此处使用不同的内核大小来消除更多噪音,但增加内核大小也会删除文本细节

在此处输入图像描述

Next we find contours and filter using contour area with a maximum threshold area to remove the small particles.接下来,我们找到轮廓并使用具有最大阈值区域的轮廓区域进行过滤以去除小颗粒。 We fill in the contour to effectively remove the noise我们填充轮廓以有效去除噪声

在此处输入图像描述

Finally we invert the image to get our result最后我们反转图像得到我们的结果

在此处输入图像描述

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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM