【问题标题】:Tesseract dont recognize captcha in png file, which contains numbers and letters of the English alphabetTesseract 无法识别 png 文件中的验证码,该文件包含英文字母的数字和字母
【发布时间】:2018-08-01 08:30:18
【问题描述】:

我需要从 url 中提取验证码并使用 Tesseract 识别它。我的代码是:

#!/usr/bin/perl -X
###
$user = 'user'; #Enter your username here
$pass = 'pass'; #Enter your password here
###
#Server settings
$home = "http://perltest.adavice.com";
$url = "$home/c/test.cgi?u=$user&p=$pass";
#Get HTML code!
$html = `GET "$url"`
###Add code here!
#Grab img from HTML code
if ($html =~ m%img[^>]*src="(/[^"]*)"%s)
{
    $img = $1;
}
###
die "<img> not found\n" if (!$img);
#Download image to server (save as: ocr_me.img)
print "GET '$home$img' > ocr_me.img\n";
system "GET '$home$img' > ocr_me.img";
###Add code here!
#Run OCR (using shell command tesseract) on img and save text as ocr_result.txt
system("tesseract ocr_me.img ocr_result");
print "GET '$txt' > ocr_result.txt\n";
system "GET '$txt' > ocr_result.txt";
###
die "ocr_result.txt not found\n" if (!-e "ocr_result.txt");
# check OCR results:
$txt = 'cat ocr_result.txt';
$txt =~ s/[^A-Za-z0-9\-_\.]+//sg;
$img =~ s/^.*\///;
print `echo -n "file=$img&text=$txt" | POST "$url"`;

图像解析正确。此图像包含验证码,如下所示:

我的输出是:

GET 'http://perltest.adavice.com/captcha/1533110309.png' > ocr_me.img
Tesseract Open Source OCR Engine v3.02.02 with Leptonica
GET '' > ocr_result.txt
Captcha text not specified

如您所见,脚本正确解析图像。但是 Tesseract 在那个 PNG 文件中没有看到任何内容。我正在尝试使用 shell 命令 tesseract 指定其他参数,例如 -psm 和 -l,但这也没有给出任何结果

更新:阅读@Dave Cross 的回答后,我尝试了他的建议。

在输出中我得到:

http://perltest.adavice.com/captcha/1533141024.png
ocr_me.img
Tesseract Open Source OCR Engine v3.02.02 with Leptonica
[]
200Captcha text not specified
Original image file not specified
Captcha text not specified

为什么我需要图像 .PNG 中的文本?也许这些额外的信息可以帮助你。 看那个:

这就是 $url 在浏览器中的样子。我的目标是使用 perl 在 wim 中为该页面创建查询。为此,我需要填写我的 $user、$pass 和 $txt 上方的表格(通过 Tesseract 图像识别)。并使用 POST 'url'(代码中的最后一个字符串)发送。

【问题讨论】:

  • 你确定没有?文件“ocr_result”包含什么?
  • 看起来你没有在任何地方定义 $txt 所以你有一个空的 ocr_result.txt
  • use strict; use warnings;添加到所有脚本的顶部,并使用my(例如my $variable)初始化变量以帮助消除简单的错误。
  • @Chris Turner,“ocr_result”需要包含验证码中的文本。但在我之前的代码中,我可以看到,我没有从 Tesseract 得到任何文本到这个文件
  • @Oysiyl:像程序员一样思考。

标签: perl ocr tesseract captcha


【解决方案1】:

这里发生了一些奇怪的事情。其中任何一个都可能导致您的问题。

  1. 在你的 shebang 线上有-X 是个糟糕的主意。它明确关闭警告。我建议您删除它,将use warnings 添加到您的代码中并修复所有显示的问题(我建议您也添加use strict,但您需要声明所有变量)。
  2. 我建议使用LWP::Simple 而不是GET
  3. 请不要使用正则表达式来解析 HTML。请改用真正的 HTML 解析器。 Web::Query 是我目前最喜欢的。
  4. 然后您再次运行GET,使用一个名为$txt 的变量,该变量没有值。那是行不通的!
  5. $txt = 'cat ocr_result.txt' 没有做你认为的事情。您需要反引号,而不是单引号。

更新:显然,我无权访问您的用户名或密码,因此无法重建您的所有代码。但这似乎适用于访问示例中的图像并从中提取文本。

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

use LWP::Simple;

my $img_url  = 'http://perltest.adavice.com/captcha/1533110309.png';
my $img_file = 'ocr_me.img';

getstore($img_url, $img_file);

my $txt = `tesseract $img_file stdout`;

say $txt;

这是您的实际错误:

system("tesseract ocr_me.img ocr_result");
print "GET '$txt' > ocr_result.txt\n";
system "GET '$txt' > ocr_result.txt";

您要求tesseract 将其输出写入ocr_result.txt,但两行之后,您使用对GET 的失败调用的输出覆盖该文件。我不确定你认为这会做什么,但它会丢弃 tesseract 已经存储在该文件中的任何输出。

更新更新:

这是我当前版本的代码:

#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use LWP::Simple qw[$ua get getstore];
use File::Basename;
###
my $user = 'xxxx'; #Enter your username here
my $pass = 'xxxx'; #Enter your password here
###
#Server settings
my $home = "http://perltest.adavice.com";
my $url = "$home/c/test.cgi?u=$user&p=$pass";
#Get HTML code!
my $html = get($url);
my $img;
###Add code here!
#Grab img from HTML code
if ($html =~ m%img[^>]*src="(/[^"]*)"%s)
{
    $img = $1;
}
my $img_url = $home . $img;
my $img_file = 'ocr_me.img';

getstore($img_url, $img_file);

say $img_url;
say $img_file;

# Looks like tesseract adds two newlines to its output -
# so chomp() it twice!
chomp(my $txt = `tesseract ocr_me.img stdout`);
chomp($txt);

say "[$txt]";

$txt =~ s/\W+//g;

my $resp = $ua->post($url, {
  u    => $user,
  p    => $pass,
  file => basename($img),
  text => $txt,
});

print $resp->code;
print $resp->content;

我改变了一些东西。

  1. 已将 $img_url$url . $img 更正为 $home . $img(这是阻止它获取正确图像的原因)。
  2. 全部改用 LWP::Simple(更简单)。
  3. chomped(两次!)tesseract 的输出以删除换行符。
  4. 使用 File::Basename 获取正确的文件名以传递最终的 POST
  5. $txt 之前删除了 $txt 中的所有非单词字符。

它仍然无法正常工作。它似乎挂起等待服务器的响应。但恐怕我没时间帮你了。

【讨论】:

  • @Oysiyl 您没有正确更新它 - 请注意 Dave 运行 tesseract 的方式与您现在运行它的方式之间的差异。
  • @Chris Turner,我知道我忘记了标准输出。立即更改代码
  • @DaveCross,感谢您的帮助!我会尽量准确一点。很抱歉占用您这么多时间。现在我看到我错误地选择了地址,我在这个网站上的问题的好处并没有我想象的那么大。要执行我的请求,我需要在 SSH 协议上使用 Putty 提升服务器。也许这就是我的脚本看不到图片的原因..
猜你喜欢
  • 2020-06-14
  • 2017-10-21
  • 1970-01-01
  • 2011-02-28
  • 1970-01-01
  • 1970-01-01
  • 2019-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多