【问题标题】:How to preprocess an image to remove noise and extract text Python?预处理图像以提取文本并去除噪声
【发布时间】:2019-09-09 08:12:21
【问题描述】:

[![在此处输入图像描述][1]][1]我有一张非常嘈杂的图像,我必须对其执行 OCR。附加的 sn-p 是更大图像的一部分。我将如何以最佳方式预处理此图像?

我已经尝试使用 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)

【问题讨论】:

  • 发布原图

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


【解决方案1】:

这是一种消除噪音的方法

  • 将图像转换为灰度和 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()

【讨论】:

  • 但这并没有使文本仍然处于待提取的令人满意的状态。文字仍有污迹,字符识别困难
  • 对于这种情况,文本很难增强。预处理文本的典型方法是使用锐化过滤器或直方图均衡来增强对比度。但在你的情况下,文本被弄脏了,所以最好的方法是使用形态学操作。另一种可能的方法是尝试将图像骨架化。您可以使用imutils 库和skeletonize() 函数来完成此操作
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-30
  • 1970-01-01
  • 2017-07-05
  • 2014-05-22
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
相关资源
最近更新 更多