Python验证码上的图像处理如何去噪
Python Image Processing on Captcha how to remove noise
我对图像处理很陌生,我想做的是清除验证码中的噪音;
对于验证码,我有不同类型的:
对于第一个,我所做的是:
首先,我将每个非黑色像素都转换为黑色。然后,我从图像中找到了一个噪声图案并将其删除。对于第一个验证码,很容易清除它,我找到了带有tesseract的文本。
但是我正在寻找第二个和第三个的解决方案。
这会怎样?我的意思是清除它的可能方法是什么?
这是我删除模式的方式:
def delete(searcher,h2,w2):
h = h2
w = w2
search = searcher
search = search.convert("RGBA")
herear = np.asarray(search)
bigar = np.asarray(imgCropped)
hereary, herearx = herear.shape[:2]
bigary, bigarx = bigar.shape[:2]
stopx = bigarx - herearx + 1
stopy = bigary - hereary + 1
pix = imgCropped.load()
for x in range(0, stopx):
for y in range(0, stopy):
x2 = x + herearx
y2 = y + hereary
pic = bigar[y:y2, x:x2]
test = (pic == herear)
if test.all():
for q in range(h):
for k in range(w):
pix[x+k,y+q] = (255,255,255,255)
对不起变量名,我只是在测试功能。
谢谢..
这是我所能得到的:
您可能知道 medianBlur
函数,该函数在每个核中找到中值并将该值代入核的中心。我们可以做类似的事情,但不是中位数,而是使用最大值然后是最小值。也有中值模糊,我得到了一些结果。我知道它们并不完美,但我希望它能给你一些想法(你可以调整输入图像和内核的大小,它可能会使结果更好一点)。
我现在没有安装 python,所以我分享我使用过的确切 C++ 代码:
Mat im1 = imread("E:/1/3.jpg", 0);
Mat im2, im3;
im2 = Mat::zeros(im1.size(), CV_8U);
for (size_t i = 1; i < im1.rows-1; i++)
{
for (size_t j = 1; j < im1.cols-1; j++)
{
double minVal, maxVal = 0;
minMaxIdx(im1(Rect(j - 1, i - 1, 3, 3)), &minVal, &maxVal);
im2.at<uchar>(i, j) = maxVal;
}
}
imshow("(1) max bluring", im2);
medianBlur(im2, im2, 3);
imshow("(2) median bluring", im2);
im2.copyTo(im1);
im2 = Mat::zeros(im1.size(), CV_8U);
for (size_t i = 1; i < im1.rows - 1; i++)
{
for (size_t j = 1; j < im1.cols - 1; j++)
{
double minVal, maxVal = 0;
minMaxIdx(im1(Rect(j - 1, i - 1, 3, 3)), &minVal, &maxVal);
im2.at<uchar>(i, j) = minVal;
}
}
imshow("(3) min bluring", im2);
Mat tmp;
double st = threshold(im2, tmp, 10, 255, THRESH_OTSU);
threshold(im2, im2, st + 14, 255, THRESH_BINARY_INV);
//dilate(im2, im2, Mat::ones(3, 3, CV_8U));
imshow("(4) final", im2);
waitKey(0);
顺便说一句,在这种情况下,像 YOLO 和 RCNN 这样的深度学习方法是最好的方法。也试试吧。
您可以使用opencv 库进行图像处理。非常有用 be this opencv documentation page。然后尝试通过 findCountour 方法提取您的号码,例如:
import cv2
import numpy as np
image = cv2.imread('C:\E0snN.png')
cv2.waitKey(0)
# Grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.bitwise_not(gray)
# Threshold
ret,thresh = cv2.threshold(gray,150,255,1)
# Get countours
contours,h = cv2.findContours(thresh,1,2)
# Draw
cv2.drawContours(image, contours, -1, (0, 255, 0), 3)
cv2.imshow('Contours', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
之后有如下结果:
它远非完美,但如果您尝试使用不同的阈值,例如:
ret,thresh = cv2.threshold(gray,127,255,1)
你可以获得更好的结果。
这是我的解决方案,
首先我得到了背景图案(在油漆上手工编辑)。来自:
之后,我创建了一个空白图像来填充图案和图像之间的差异。
img = Image.open("x.png").convert("RGBA")
pattern = Image.open("y.png").convert("RGBA")
pixels = img.load()
pixelsPattern = pattern.load()
new = Image.new("RGBA", (150, 50))
pixelNew = new.load()
for i in range(img.size[0]):
for j in range(img.size[1]):
if(pixels[i,j] != pixelsPattern[i,j]):
pixelNew[i,j] = pixels[i,j]
new.save("differences.png")
区别如下..
最后,我添加了模糊并清除了不是黑色的位。
结果:
pytesseract 的结果是 2041,这张图片是错误的,但一般率在 %60 左右。
我对图像处理很陌生,我想做的是清除验证码中的噪音;
对于验证码,我有不同类型的:
对于第一个,我所做的是:
首先,我将每个非黑色像素都转换为黑色。然后,我从图像中找到了一个噪声图案并将其删除。对于第一个验证码,很容易清除它,我找到了带有tesseract的文本。
但是我正在寻找第二个和第三个的解决方案。
这会怎样?我的意思是清除它的可能方法是什么?
这是我删除模式的方式:
def delete(searcher,h2,w2):
h = h2
w = w2
search = searcher
search = search.convert("RGBA")
herear = np.asarray(search)
bigar = np.asarray(imgCropped)
hereary, herearx = herear.shape[:2]
bigary, bigarx = bigar.shape[:2]
stopx = bigarx - herearx + 1
stopy = bigary - hereary + 1
pix = imgCropped.load()
for x in range(0, stopx):
for y in range(0, stopy):
x2 = x + herearx
y2 = y + hereary
pic = bigar[y:y2, x:x2]
test = (pic == herear)
if test.all():
for q in range(h):
for k in range(w):
pix[x+k,y+q] = (255,255,255,255)
对不起变量名,我只是在测试功能。
谢谢..
这是我所能得到的:
您可能知道 medianBlur
函数,该函数在每个核中找到中值并将该值代入核的中心。我们可以做类似的事情,但不是中位数,而是使用最大值然后是最小值。也有中值模糊,我得到了一些结果。我知道它们并不完美,但我希望它能给你一些想法(你可以调整输入图像和内核的大小,它可能会使结果更好一点)。
我现在没有安装 python,所以我分享我使用过的确切 C++ 代码:
Mat im1 = imread("E:/1/3.jpg", 0);
Mat im2, im3;
im2 = Mat::zeros(im1.size(), CV_8U);
for (size_t i = 1; i < im1.rows-1; i++)
{
for (size_t j = 1; j < im1.cols-1; j++)
{
double minVal, maxVal = 0;
minMaxIdx(im1(Rect(j - 1, i - 1, 3, 3)), &minVal, &maxVal);
im2.at<uchar>(i, j) = maxVal;
}
}
imshow("(1) max bluring", im2);
medianBlur(im2, im2, 3);
imshow("(2) median bluring", im2);
im2.copyTo(im1);
im2 = Mat::zeros(im1.size(), CV_8U);
for (size_t i = 1; i < im1.rows - 1; i++)
{
for (size_t j = 1; j < im1.cols - 1; j++)
{
double minVal, maxVal = 0;
minMaxIdx(im1(Rect(j - 1, i - 1, 3, 3)), &minVal, &maxVal);
im2.at<uchar>(i, j) = minVal;
}
}
imshow("(3) min bluring", im2);
Mat tmp;
double st = threshold(im2, tmp, 10, 255, THRESH_OTSU);
threshold(im2, im2, st + 14, 255, THRESH_BINARY_INV);
//dilate(im2, im2, Mat::ones(3, 3, CV_8U));
imshow("(4) final", im2);
waitKey(0);
顺便说一句,在这种情况下,像 YOLO 和 RCNN 这样的深度学习方法是最好的方法。也试试吧。
您可以使用opencv 库进行图像处理。非常有用 be this opencv documentation page。然后尝试通过 findCountour 方法提取您的号码,例如:
import cv2
import numpy as np
image = cv2.imread('C:\E0snN.png')
cv2.waitKey(0)
# Grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.bitwise_not(gray)
# Threshold
ret,thresh = cv2.threshold(gray,150,255,1)
# Get countours
contours,h = cv2.findContours(thresh,1,2)
# Draw
cv2.drawContours(image, contours, -1, (0, 255, 0), 3)
cv2.imshow('Contours', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
之后有如下结果:
它远非完美,但如果您尝试使用不同的阈值,例如:
ret,thresh = cv2.threshold(gray,127,255,1)
你可以获得更好的结果。
这是我的解决方案,
首先我得到了背景图案(在油漆上手工编辑)。来自:
之后,我创建了一个空白图像来填充图案和图像之间的差异。
img = Image.open("x.png").convert("RGBA")
pattern = Image.open("y.png").convert("RGBA")
pixels = img.load()
pixelsPattern = pattern.load()
new = Image.new("RGBA", (150, 50))
pixelNew = new.load()
for i in range(img.size[0]):
for j in range(img.size[1]):
if(pixels[i,j] != pixelsPattern[i,j]):
pixelNew[i,j] = pixels[i,j]
new.save("differences.png")
区别如下..
最后,我添加了模糊并清除了不是黑色的位。
结果:
pytesseract 的结果是 2041,这张图片是错误的,但一般率在 %60 左右。