任何花了大量时间在互联网上的人都知道模因用法在网络话语中的流行程度。寻找新的最新发生的迷因并与不同的朋友分享分享幽默的团体是我长期以来喜欢的消遣。工作在科技和信息安全领域给我带来了意外的收获“终端在线”的朋友群,他们都是这样做的。
然而,对于大多数模因来说,都有一种讽刺的双重性:它们的生态位越高它们往往越有趣。一些最好的迷因只是我的朋友小组之间的笑话,或来自令人难以置信的利基InfoSec行业。
这提出了一个极为常见的问题:我永远找不到合适的位置当我最需要他们的时候,我想送他们一些模因。中间转换,一时的精神迷因总是不可能找到的。滚动通过手机中保存的数百幅图像进行搜索效率不高事实证明,所以我决定尝试更好地解决这个问题。
一种OCR实现
之前编写迷因搜索引擎的尝试最终导致了一个核心阻塞问题:缺乏可伸缩的OCR。所有现有解决方案要么是极不善于识别扭曲和高度变异大多数迷因的文本,或是昂贵得令人望而却步。
例如,Tesseract公司光学字符识别是免费的从图像中提取文本的开源库。使用此测试时它可以用非常标准的字体和颜色方案:
示例easy-to-OCR meme,Tesseract结果:我应该感觉到打盹醒来后神清气爽,但我最终感觉这
然而,模因的重新组合、水印和重新共享使其格式化除标准之外的任何内容。以下面的迷因为例:
Tesseract声明此迷因的OCR-ed文本是:30蓝色41人;?S4-5英寸flew/-V\[IL'.“,2;g”.'Sj/B“f;T”EArmD和[red\]mvslmunlm:锯木厂
这与实际文本相差甚远人类可以分辨。似乎我的选择要么是昂贵的云OCR服务,或像这样性能较差的解决方案。
然而,一天晚上,当我试图发送某人是我iPhone上的老派CAPTCHA图像示例:
在上一代中意外选择模糊文本reCAPTCHA图像。
令我惊讶的是,iOS非常高兴地强调CAPTCHA图像的故意填充和扭曲文本。甚至更多令人惊讶的是,它完美地解码了文本:
粘贴复制的reCAPTCHA文本。
如果它对故意混淆的文本图像做得很好,那么它会如何它符合大多数模因的各种形式?测试后我手机中保存的一堆迷因上的OCR,答案似乎是“非常好”。
更好的是,在快速搜索后,我发现这个功能是在iOS中暴露愿景框架.这意味着该OCR可以以定制iOS的形式完全自动化应用程序。最后,似乎有一个可扩展的OCR解决方案来解决这个问题我一直在面对!
数百万Meme的廉价可扩展OCR
虽然我写了很多代码,但我从来没有写过任何严肃的东西在Swift或Objective C中,我找不到任何愿景框架的插件阿帕奇科尔多瓦,所以我不能只写JavaScript中的应用程序。看起来是时候咬了用Swift编写OCR iOS服务器。
通过结合激烈的谷歌搜索的力量,对各种Github上的快速回购,以及偶尔对我的iOS提出的Xcode问题朋友,我能够拼凑出一个可行的解决方案:
在iPhone上运行的非常基本的iOS Vision OCR服务器。
我在Macbook上的初步速度测试相当慢。然而,有一次我将该应用程序部署到实际的iPhone上,OCR的速度极快有希望(可能是因为愿景框架使用通用分组).然后,我能够对数千张图像执行极其精确的OCR很快,即使是像第二代SE这样的廉价iPhone型号。
总的来说,API服务器构建在GCD Web服务器运行得相当好,但确实出现了轻微的内存泄漏。之后被OCR-ed的20K-40K图像应用程序通常会崩溃,这是一个相当大的烦恼。再次,我对斯威夫特的熟悉程度不相上下用一个金毛猎犬对金融,因此调试这个问题被证明相当棘手。在调查了更多“黑客”选项后,我意识到我可以利用“引导访问”在iOS上到应用程序崩溃时自动重启。这基本上起作用了作为守护程序,以确保OCR服务器继续为请求提供服务还可以防止其他未知的崩溃,因为损坏的图像会停止管道。
使用ElasticSearch进行全文搜索
现在,通过一种方法从所有模因图像中正确提取文本现在的问题是如何快速搜索大量文本。使用进行初始测试Postgres全文搜索事实证明,索引功能在任何规模上都非常慢超过一百万个映像,即使分配了适当的硬件资源。
我决定放弃弹性搜索这是一次尝试,因为它基本上是专门为这个问题定制的。之后文档阅读、早期测试和阅读实际使用中的博客帖子关于它,我得出了一些关于实现它以供我使用的结论案例:
- ElasticSearch非常需要RAM和系统资源尤其是在运行多个节点时。具有多个节点允许故障恢复能力当它们发生时,这在任何分布式系统中都很常见。
- 我可以在一个单节点集群,因为对于ElasticSearch通常的规模来说,即使是数百万个迷因的组合文本也还不够大。这将具有成本效益,但当然是以可靠性为代价的。
- 由于我正在使用Postgres处理模因的其余结构化数据(例如上下文、源代码等),因此将模因文本存储在ElasticSearch中会使“单一真相来源“范式。根据以往的经验,必须确保两个来源的真相一致,这可能是极端复杂和令人头痛的根源。
- 经过搜索,我发现我可以利用PGSync(PGSync)自动将选中的Postgres列同步到ElasticSearch。这似乎是一个很好的折衷方案,可以在单节点配置中保持单一真相来源(Postgres)并经济高效地运行ElasticSearch。如果有任何数据丢失,我可以取消ElasticSearch,而PGSync将允许我轻松重建文本搜索索引。
- ElasticSearch具有大量的文本搜索可配置性和完整的REST API,使我能够轻松地将其集成到我的服务中。
我的最终设计如下:
下面是最终实施的极随机图。
使用生成的数据集进行的测试表明,它的扩展性非常好,甚至可以在不到一秒钟的时间内搜索数百万个迷因在相对温和的硬件上。在撰写本文时,我能够索引和搜索大约1700万个共享模因的文本只有6个内核和16GB RAM的Linode实例。这样可以节省成本相对较低,如果您打算这样做,这对于次要项目很重要让它们运行任意时间。
视频Memes、ffmpeg和OCR
事实证明,模因并不仅仅是图像。现在有很多模因视频以及音频曲目。这无疑是由于移动网络的改进允许快速交付更大的文件。在某些情况下,像GIF,视频甚至更好,因为它们有很多更好的压缩,因此尺寸可以小得多。
为了索引这种类型的模因,视频必须被切碎变成一组屏幕截图,然后像常规一样OCRed模因。为了解决这个问题,我编写了一个小型微服务以下内容:
- 获取输入视频文件。
- 使用ffmpeg(通过库),拉出视频中的十个等距截图.
- 将屏幕截图文件发送到iPhone OCR服务。
- 在对视频文件中的每个屏幕快照进行OCRing后返回结果集。
将iPhone OCR服务升级为OCR群集
毫无疑问,这增加了OCR服务的负载明显地。对于每一个视频迷因来说,它基本上是10倍的工作量进行OCR。尽管OCR应用服务器的速度很快,但这还是成为了一个主要问题瓶颈,我最终选择将iOS OCR服务升级为集群:
别担心,有一个风扇让他们保持凉爽。
由于使用了许多iPhone,此设置看起来相当昂贵。然而,有一些事情对我有利,使我受益匪浅比您预期的便宜:
- 由于这些专用于通过iOS Vision API,我可以使用旧的(和便宜的)iPhone型号,例如iPhone SE(第二代).
- 我的优点是不在乎屏幕裂纹、划痕和其他外观问题,这会进一步降低成本。
- 更好的是,我甚至不想把它们用作手机,所以即使是iPhoneIMEI被禁止或者锁定在不受欢迎的网络上,对我来说非常好。
考虑到所有这些因素,我找到了iPhone价格便宜得多。例如,这里有一个清单符合我的标准,价格实惠:
这部手机可能只卖了40美元,因为它被锁定在了不受欢迎的美国承运人(板球),因此大多数人都不想成为坚持下去。
这些成本与云OCR服务相比如何?GCP的Cloud Vision API每向您收取1.50美元千幅图像光学字符识别。这意味着使用这种自制的解决方案,我们可以抵消iPhone的成本大约27K张图像之后。当然,也许GCP的OCR服务要好得多就质量而言,但在我的测试中,结果似乎与这个用例。尝试以数十种规模使用云API数以百万计的OCR请求和成本对于这个项目。
密切关注eBay拍卖会我买了任何一款iPhone如此低廉的利率。使用我在house,我配置它作为Nginx负载平衡器来传播在iPhone上均匀发送请求。添加一些网络,以及便宜的风扇可以让一切保持凉爽,我有一个可以工作的OCR集群可以轻松应对更大的需求。
最终(复杂)架构
最终的架构看起来与上图类似。虽然由于我的优化,确实有一些额外的复杂性就成本而言,更便宜的基础设施将使我能够运行这一边项目时间更长。
总的来说,这是一个有趣的项目,附带的好处是有大量个人效用。我学到了很多关于各种主题的知识,包括ElasticSearch配置、iOS应用程序开发,以及机器学习。在以后的帖子中,我希望详细介绍一些我为它构建的其他功能,包括:
- “按图像搜索”/“图像相似性”搜索数百万模因。
- NSFW模因的自动检测和标记。
- 构建抓取基础设施,以实际索引所有模因。
如果你想试试,请访问网站https://findthatmeme.com网站让我知道你的想法!