猿问

如何使用 Google Vision Api 检测块内的所有文本

我正在尝试使用 google vision api 从图像中提取文本,它有效。但我只想检测图像的一部分以获得某些文本。

这是我使用的图像

我只想提取所有文本,maybank2u.com直到From Account: 我知道有一些教程可以通过使用块来完成这个技巧,但这些教程是不同的编程语言。


我的代码:


<div class="row">

    <div class="col-12">

        <ol>

            <?php foreach ($text as $key => $texts): ?> 

                <li><h6> <?php echo ucfirst($texts->info()['description']) ?></h6><<br><br> 

                </li>

            <?php endforeach ?>

        </ol>

    </div>

</div>

此代码将从图像中获取所有文本


输出:

http://img3.mukewang.com/61d161c40001822214640608.jpg

慕村225694
浏览 188回答 2
2回答

大话西游666

下面的代码对我有用。我有一个 php 文件 test.php 和一个图像文件 /images/UUIPXl.png。为了获取每一行文本,我迭代了来自 Google Vision 的文本注释,并创建了一个行项目数组。每一个都有一个 x 位置和一个文本值。然后我按 x 位置对每一行进行排序并连接以创建一行文本。最后,一旦我们获得最终所需的文本行,我们就停止。我得到这样的结果:maybank2u.com打开账单支付状态:成功参考编号:2950211545交易日期:2016年2月1日13:09:17金额:RM100.00来自账户 564155051577 WCAphp代码:<?php&nbsp;&nbsp; &nbsp; require 'vendor/autoload.php';&nbsp; &nbsp; use Google\Cloud\Vision\VisionClient;&nbsp; &nbsp; $config = ["keyFile" => json_decode(file_get_contents("./APIKey.json"), true) ];&nbsp; &nbsp; $vision = new VisionClient($config);&nbsp; &nbsp; $image = $vision->image(&nbsp; &nbsp; &nbsp; &nbsp; fopen('./images/UUIPXl.png', 'r'),&nbsp; &nbsp; &nbsp; &nbsp; ['TEXT_DETECTION']&nbsp; &nbsp; );&nbsp; &nbsp; $textAnnotations = $vision->annotate($image)->text();&nbsp; &nbsp; $rows = [];&nbsp; &nbsp; // Function used to sort our lines.&nbsp; &nbsp; function sortProc($a, $b)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if ($a["x"] === $b["x"]) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 0;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return ($a["x"] < $b["x"]) ? -1 : 1;&nbsp; &nbsp; }&nbsp; &nbsp; // Remove first row (complete text).&nbsp; &nbsp; array_shift($textAnnotations);&nbsp; &nbsp; // We should calculate this, use a reasonable value to begin with.&nbsp; &nbsp; $lineHeight = 8;&nbsp; &nbsp; foreach ($textAnnotations as $text) {&nbsp; &nbsp; &nbsp; &nbsp; $key = round(((double)($text->info()["boundingPoly"]["vertices"][0]["y"]))/$lineHeight);&nbsp; &nbsp; &nbsp; &nbsp; $x = (int)$text->info()["boundingPoly"]["vertices"][0]["x"];&nbsp; &nbsp; &nbsp; &nbsp; $value = ["x" => $x, "text" => $text->description()];&nbsp; &nbsp; &nbsp; &nbsp; if (!isset($rows[$key])) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $rows[$key] = [];&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; $rows[$key][] = $value;&nbsp; &nbsp; }&nbsp; &nbsp; $text = [];&nbsp; &nbsp; foreach ($rows as $key => $value) {&nbsp; &nbsp; &nbsp; &nbsp; // Sort by x value.&nbsp; &nbsp; &nbsp; &nbsp; usort($value, "sortProc");&nbsp; &nbsp; &nbsp; &nbsp; // Concatenate each line&nbsp; &nbsp; &nbsp; &nbsp; $result = array_reduce($value, function($acc, $elem) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $acc .= " " . $elem["text"];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return $acc;&nbsp; &nbsp; &nbsp; &nbsp; }, "");&nbsp; &nbsp; &nbsp; &nbsp; $text[] = $result;&nbsp; &nbsp; &nbsp; &nbsp; // Stop when we get here!&nbsp; &nbsp; &nbsp; &nbsp; if (preg_match("/from account/i", $result)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }?><div class="row" style="padding: 20px;">&nbsp; &nbsp; <div class="col-12">&nbsp; &nbsp; &nbsp; &nbsp; <ul>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <?php foreach ($text as $row): ?>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <li><h3> <?php echo ucfirst($row) ?></h3></li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <?php endforeach ?>&nbsp; &nbsp; &nbsp; &nbsp; </ul>&nbsp; &nbsp; </div></div>

倚天杖

如果您只想限制输出及其每次应该停止执行的相同字符串,请执行以下操作:<div class="row">&nbsp; &nbsp; <div class="col-12">&nbsp; &nbsp; &nbsp; &nbsp; <ol>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <?php foreach ($text as $key => $texts): ?>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <?php if (strpos($texts->info()['description'], 'From Account') !== false) break; ?>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <li><h6> <?php echo ucfirst($texts->info()['description']) ?></h6><<br><br>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <?php endforeach ?>&nbsp; &nbsp; &nbsp; &nbsp; </ol>&nbsp; &nbsp; </div></div>说明:如果$texts->info()['description']包含文本,From Account它将通过 结束 foreach 循环的执行break。如果您需要检查多个关键字,请阅读此内容。另一种解决方案是在将图像imagecrop()发送到 API 之前裁剪图像。但是为此,您需要确保它永远不会改变文本的大小/位置。PS 你确定每个人都应该在你的截图中看到那些私人数据吗?Update1正如你所问的。这将是相同的代码,但使用控制结构的替代语法:<div class="row">&nbsp; &nbsp; <div class="col-12">&nbsp; &nbsp; &nbsp; &nbsp; <ol>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <?php foreach ($text as $key => $texts): ?>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <?php if (strpos($texts->info()['description'], 'From Account') !== false): ?>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <?php break; ?>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <?php endif; ?>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <li><h6> <?php echo ucfirst($texts->info()['description']) ?></h6><<br><br>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <?php endforeach ?>&nbsp; &nbsp; &nbsp; &nbsp; </ol>&nbsp; &nbsp; </div></div>也许这可以解决您的问题,因为同一页面包含此注释:不支持在同一控制块中混合使用语法。更新2在你更新你的问题之后,它现在更清楚了。输出的每一行不包含一个元素。相反,它包含多行文本。因此,我的第一个代码没有回显它From Account在第一个数组元素中找到的任何内容。因此,我们需要搜索字符串From Account 并剪切文本行:<div class="row">&nbsp; &nbsp; <div class="col-12">&nbsp; &nbsp; &nbsp; &nbsp; <ol>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <?php foreach ($text as $key => $texts): ?>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <?php&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $text = $texts->info()['description'];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // search for string&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $pos = strpos($texts->info()['description'], 'From Account');&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ($pos !== false) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // if the string was found cut the text&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $text = substr($text, 0, $pos);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ?>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <li><h6> <?php echo $text ?></h6><<br><br>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </li>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <?php endforeach ?>&nbsp; &nbsp; &nbsp; &nbsp; </ol>&nbsp; &nbsp; </div></div>您可以选择在此之前添加它<?php endforeach ?>以跳过以下所有数组元素:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <?php&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ($pos !== false) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ?>注意: @TerryLennox 用于preg_match查找From Account. 这和 using 没有区别strpos(最喜欢避免 regex)。但他的回答包含另一个很好的提示。他使用文本位置信息将文本逐行添加到新数组中。这可能非常有用,具体取决于您的目标如何显示/存储文本。
随时随地看视频慕课网APP
我要回答