python - 使用 OpenCV 进行图像处理,去除图像中的背景文本和噪声

标签 python image opencv image-processing computer-vision

我有这些图片

enter image description here

enter image description here

我想删除背景中的文本。仅应保留验证码字符(即 K6PwKA、YabVzu)。任务是稍后使用 tesseract 识别这些字符。

这是我尝试过的,但它并没有提供很好的准确性。

import cv2
import pytesseract

pytesseract.pytesseract.tesseract_cmd = r"C:\Users\HPO2KOR\AppData\Local\Tesseract-OCR\tesseract.exe"
img = cv2.imread("untitled.png")
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray_filtered = cv2.inRange(gray_image, 0, 75)
cv2.imwrite("cleaned.png", gray_filtered)

我该如何改进?

注意: 我尝试了针对这个问题得到的所有建议,但没有一个对我有用。

编辑: 根据 Elias 的说法,我尝试使用 Photoshop 将验证码文本的颜色转换为灰度,结果介于 [100, 105] 之间。然后我根据这个范围对图像进行阈值设置。但我得到的结果并没有给出令人满意的 tesseract 结果。

gray_filtered = cv2.inRange(gray_image, 100, 105)
cv2.imwrite("cleaned.png", gray_filtered)
gray_inv = ~gray_filtered
cv2.imwrite("cleaned.png", gray_inv)
data = pytesseract.image_to_string(gray_inv, lang='eng')

输出:

'KEP wKA'

结果:

enter image description here

编辑2:

def get_text(img_name):
    lower = (100, 100, 100)
    upper = (104, 104, 104) 
    img = cv2.imread(img_name)
    img_rgb_inrange = cv2.inRange(img, lower, upper)
    neg_rgb_image = ~img_rgb_inrange
    cv2.imwrite('neg_img_rgb_inrange.png', neg_rgb_image)
    data = pytesseract.image_to_string(neg_rgb_image, lang='eng')
    return data

给出:

enter image description here

文本为

GXuMuUZ

有没有办法让它软一点

最佳答案

以下是两种可能的方法和一种纠正扭曲文本的方法:

方法#1:形态运算+轮廓过滤

  1. 获取二值图像。 Load image , grayscale ,然后 Otsu's threshold .

  2. 删除文本轮廓。使用 cv2.getStructuringElement() 创建一个矩形内核。然后执行 morphological operations消除噪音。

  3. 过滤并消除微小噪音。 Find contours并使用 contour area 进行过滤去除小颗粒。我们通过用 cv2.drawContours() 填充轮廓来有效去除噪声。

  4. 执行 OCR。我们反转图像,然后应用轻微的 Gaussian blur 。然后我们使用Pytesseract进行OCR与 --psm 6配置选项将图像视为单个文本 block 。看Tesseract improve quality用于改进检测的其他方法和 Pytesseract configuration options用于其他设置。

<小时/>

输入图片->二进制 ->变形开口

enter image description here enter image description here enter image description here

轮廓区域过滤->反转->应用模糊以获得结果

enter image description here enter image description here enter image description here

OCR结果

YabVzu

代码

import cv2
import pytesseract
import numpy as np

pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"

# Load image, grayscale, Otsu's threshold
image = cv2.imread('2.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Morph open to remove noise
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2,2))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=1)

# Find contours and remove small noise
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 < 50:
        cv2.drawContours(opening, [c], -1, 0, -1)

# Invert and apply slight Gaussian blur
result = 255 - opening
result = cv2.GaussianBlur(result, (3,3), 0)

# Perform OCR
data = pytesseract.image_to_string(result, lang='eng', config='--psm 6')
print(data)

cv2.imshow('thresh', thresh)
cv2.imshow('opening', opening)
cv2.imshow('result', result)
cv2.waitKey()     

方法#2:颜色分割

观察到所需提取的文本与图像中的噪声具有明显的对比度,我们可以使用颜色阈值来隔离文本。这个想法是先转换为 HSV 格式,然后使用颜色阈值来获取使用较低/较高颜色范围的掩模。我们使用与 Pytesseract 相同的 OCR 流程。

<小时/>

输入图片->面膜->结果

enter image description here enter image description here enter image description here

代码

import cv2
import pytesseract
import numpy as np

pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"

# Load image, convert to HSV, color threshold to get mask
image = cv2.imread('2.png')
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 0])
upper = np.array([100, 175, 110])
mask = cv2.inRange(hsv, lower, upper)

# Invert image and OCR
invert = 255 - mask
data = pytesseract.image_to_string(invert, lang='eng', config='--psm 6')
print(data)

cv2.imshow('mask', mask)
cv2.imshow('invert', invert)
cv2.waitKey()

纠正扭曲的文本

当图像水平时,OCR 效果最佳。为了确保文本采用 OCR 的理想格式,我们可以执行透视变换。去除所有噪声以隔离文本后,我们可以执行接近变形以将各个文本轮廓合并为单个轮廓。从这里我们可以使用 cv2.minAreaRect 找到旋转的边界框然后执行 four point perspective transform使用 imutils.perspective.four_point_transform 。继续清洁面膜,结果如下:

面膜->变形关闭->检测到旋转边界框 ->结果

enter image description here enter image description here enter image description here enter image description here

与其他图像一起输出

enter image description here enter image description here enter image description here enter image description here

更新了代码以包含透视变换

import cv2
import pytesseract
import numpy as np
from imutils.perspective import four_point_transform

pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"

# Load image, convert to HSV, color threshold to get mask
image = cv2.imread('1.png')
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 0])
upper = np.array([100, 175, 110])
mask = cv2.inRange(hsv, lower, upper)

# Morph close to connect individual text into a single contour
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
close = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=3)

# Find rotated bounding box then perspective transform
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
rect = cv2.minAreaRect(cnts[0])
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(image,[box],0,(36,255,12),2)
warped = four_point_transform(255 - mask, box.reshape(4, 2))

# OCR
data = pytesseract.image_to_string(warped, lang='eng', config='--psm 6')
print(data)

cv2.imshow('mask', mask)
cv2.imshow('close', close)
cv2.imshow('warped', warped)
cv2.imshow('image', image)
cv2.waitKey()

注意:颜色阈值范围是使用此 HSV 阈值脚本确定的

import cv2
import numpy as np

def nothing(x):
    pass

# Load image
image = cv2.imread('2.png')

# Create a window
cv2.namedWindow('image')

# Create trackbars for color change
# Hue is from 0-179 for Opencv
cv2.createTrackbar('HMin', 'image', 0, 179, nothing)
cv2.createTrackbar('SMin', 'image', 0, 255, nothing)
cv2.createTrackbar('VMin', 'image', 0, 255, nothing)
cv2.createTrackbar('HMax', 'image', 0, 179, nothing)
cv2.createTrackbar('SMax', 'image', 0, 255, nothing)
cv2.createTrackbar('VMax', 'image', 0, 255, nothing)

# Set default value for Max HSV trackbars
cv2.setTrackbarPos('HMax', 'image', 179)
cv2.setTrackbarPos('SMax', 'image', 255)
cv2.setTrackbarPos('VMax', 'image', 255)

# Initialize HSV min/max values
hMin = sMin = vMin = hMax = sMax = vMax = 0
phMin = psMin = pvMin = phMax = psMax = pvMax = 0

while(1):
    # Get current positions of all trackbars
    hMin = cv2.getTrackbarPos('HMin', 'image')
    sMin = cv2.getTrackbarPos('SMin', 'image')
    vMin = cv2.getTrackbarPos('VMin', 'image')
    hMax = cv2.getTrackbarPos('HMax', 'image')
    sMax = cv2.getTrackbarPos('SMax', 'image')
    vMax = cv2.getTrackbarPos('VMax', 'image')

    # Set minimum and maximum HSV values to display
    lower = np.array([hMin, sMin, vMin])
    upper = np.array([hMax, sMax, vMax])

    # Convert to HSV format and color threshold
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv, lower, upper)
    result = cv2.bitwise_and(image, image, mask=mask)

    # Print if there is a change in HSV value
    if((phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ):
        print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax))
        phMin = hMin
        psMin = sMin
        pvMin = vMin
        phMax = hMax
        psMax = sMax
        pvMax = vMax

    # Display result image
    cv2.imshow('image', result)
    if cv2.waitKey(10) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()

关于python - 使用 OpenCV 进行图像处理,去除图像中的背景文本和噪声,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60145306/

相关文章:

python - Google Speech API 不适用于嘈杂的音频

python - 如何在 GPU 上计算成对距离矩阵

python beautiful soup 在类标签后立即获取中文

javascript - 关于图像大小调整(视口(viewport))的几个问题

asp.net-mvc - 上传包含在 MVC 模型中的图像

javascript - AngularJs - 保存在数据库中时减小图像大小

c++ - 对图像中的一系列颜色进行阈值处理

c++ - 将白色像素区域合并为一个区域 opencv c++

image-processing - 比较图像相似度的简单快速方法

python - 将实例字段作为参数传递给函数