如何从图像中消除小颗粒背景噪声?

6

我试图从我的图片中删除渐变背景噪声。我已经尝试了许多使用cv2的方法,但都没有成功。

首先将图像转换为灰度图,以使其失去一些可能有助于查找轮廓的渐变。

有人知道如何处理这种背景吗?我甚至尝试从角落取样并应用某种内核滤波器。


1
验证码实际上是为了与背景噪声难以区分而制作的。 - Klaus D.
2个回答

11
一种消除渐变的方法是使用cv2.medianBlur()对图像进行平滑处理,通过对核下的所有像素取中值来实现。然后,为提取字母,您可以执行cv2.adaptiveThreshold()

模糊会去除大部分梯度噪声。您可以更改核大小以去除更多噪声,但这也将删除字母的细节。

enter image description here

自适应阈值处理图像以提取字符。从您的原始图像中看,似乎将梯度噪声添加到字母cxz上,使其与背景融为一体。

enter image description here

接下来,我们可以执行cv2.Canny()来检测边缘并获得以下结果

enter image description here

然后,我们可以使用cv2.morphologyEx()进行形态学开运算来清除小噪声并增强细节。

enter image description here

现在,我们使用cv2.dilate()膨胀以获得单个轮廓

enter image description here

从这里开始,我们使用cv2.findContours()查找轮廓。我们遍历每个轮廓,并使用cv2.contourArea()进行过滤,使用最小和最大面积来获得边界框。根据您的图像,您可能需要调整最小/最大面积过滤器。这是结果:

enter image description here

import cv2
import numpy as np

image = cv2.imread('1.png')

blur = cv2.medianBlur(image, 7)
gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,3)

canny = cv2.Canny(thresh, 120, 255, 1)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
opening = cv2.morphologyEx(canny, cv2.MORPH_CLOSE, kernel)
dilate = cv2.dilate(opening, kernel, iterations=2)

cnts = cv2.findContours(dilate, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

min_area = 500
max_area = 7000
for c in cnts:
    area = cv2.contourArea(c)
    if area > min_area and area < max_area:
        x,y,w,h = cv2.boundingRect(c)
        cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)

cv2.imshow('blur', blur)
cv2.imshow('thresh', thresh)
cv2.imshow('canny', canny)
cv2.imshow('opening', opening)
cv2.imshow('dilate', dilate)
cv2.imshow('image', image)
cv2.waitKey(0)

0
你可以为每个像素赋一个值,定义像素的深浅程度。然后,如果有相似的数字,只需找到中位数,并将相似的像素设置为该值。 将其归一化为白色、灰色和黑色,然后就可以区分背景和字符了。

1
我认为你没有理解验证码中的渐变点。 - Mad Physicist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接