python - 带水平线的透明验证码图像
问题描述
def resolve(img_path):
image = Image.open(img_path)
new_image = Image.new("RGBA", image.size, "WHITE") # Create a white rgba background
new_image.paste(image, (0, 0), image) # Paste the image on the background.
new_image.convert('RGB').save(img_path, "JPEG") # Save as JPEG
enhancedImage = enhance(img_path)
return pytesseract.image_to_string(img_path)
def enhance(img_path):
image1 = cv2.imread(img_path)
#print(image1)
img = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
ret, thresh1 = cv2.threshold(img, 180, 255, cv2.THRESH_BINARY_INV)
#thresh = 50
#im_bw = cv2.threshold(thresh3, thresh, 255, cv2.THRESH_BINARY)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 2))
erosion = cv2.erode(thresh1, kernel, iterations = 1)
return erosion
我正在尝试解决上述图像的验证码。尝试将透明 bg 转换为白色,然后增强图像,但结果不正确。
解决方案
让我从您的代码的潜在问题开始
def enhance(img_path):
image1 = cv2.imread(img_path)
现在,如果您阅读它,imread
结果将是:
您无法pytesseract
从输出图像中读取它。
这是此答案中所述的一个已知问题:cv2 imread transparent gone
如答案中所述:
在透明图像后面放一张白色图像,这样您就可以解决问题。
我们将应用相同的技术,现在结果将是:
至于第二个图像结果将是:
我们将执行以下步骤以有效地从输出图像中读取:
-
- 调整图像大小
-
- 应用自适应阈值
对于第一张图片,结果将是:
对于第二张图像,结果将是:
现在,当您pytesseract
使用 mode 6 (modes)阅读它时,结果将是:
3daab
b42yb
代码:
import cv2
from PIL import Image
from pytesseract import image_to_string
def save_transparent_image(image_path, save_name):
image = Image.open(image_path).convert("RGBA")
canvas = Image.new(mode='RGBA',
size=image.size, color=(255, 255, 255, 255))
canvas.paste(image, mask=image)
canvas.save(save_name, format="PNG")
img_lst = ["o3upS.png", "kGpYk.png"]
for i, img_name in enumerate(img_lst):
save_image = "captcha" + str(i) + ".png"
save_transparent_image(img_name, save_image)
# Step 1: Resize the image
img = cv2.imread(save_image)
(h, w) = img.shape[:2]
img = cv2.resize(img, (w*2, h*2))
# Step 2: Apply adaptive-threshold
gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thr = cv2.adaptiveThreshold(gry, 255, cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY, 33, 79)
# Step 3: Read the threshold image
txt = image_to_string(thr, config="--psm 6")
txt = txt.split("\n")[0]
print(txt)
问题此代码是否适用于其他验证码?
不,不会的。除非验证码与给定示例相似。您需要更改adaptive-threshold
'sblock-size
和C
参数,看看它是否有效。
推荐阅读
- c# - 我的 XUnit dotnet 核心项目构建在我的桌面上,但不在 DevOps Server 2019 中
- go - 当我连续打开许多连接时,使用 MinIO 和 Go 出现“服务器保持空闲连接”错误,我该如何解决这个问题?
- javascript - 编辑方法没有检索到适当的信息 [错误] React
- r - 计算 R 中的已实现波动率
- java - 无法在 Windows 上使用 IntelliJ 创建 gradle 项目
- .net-core - ServicePoint 中的 CurrentConnections 返回零
- java - 如何在 onProgressChanges 之外获取 seekBar 的实时值?
- javascript - 从嵌套的 json 值对象中获取数组
- angular - Angular 8:将两个独立的应用程序合二为一
- python - 从低对比度图像中识别字符