零基础入门学python小甲鱼pdf,小甲鱼python课件ppt
Python部落(python.freelycode.com)组织翻译。禁止转载。欢迎转发。
我写了一个程序来清理手写笔记的扫描图片,同时减小文件大小。
输入和输出示例:
左:300 DPI,7.2MB PNG/790KB JPG。右:300DPI,121KB PNG。(注1)
声明:这次描述的过程基本上是由Office Lens应用程序实现的。也许有许多其他工具可以做同样的事情。我没有提出一个全新的发明,我只是重新实现了现有的工具。
如果没有时间,可以直接查看github库,或者跳转到结果部分,可以与3D颜色聚类程序进行交互(此翻译已将交互过程显示为gif动画,请查看原文链接参与交互)。
动机
我的一些课没有指定的课本。在这些课上,我曾经每周指定一个“学生记录员”来分享他们的课堂笔记,这样我就可以留下一些书面记录,让学生检查他们对材料的理解。这些笔记将以PDF格式上传到课程网站。
在学校,我们有一个“智能”复印机,可以扫描成PDF文件,但扫描输出的文档有点,嗯,不好看。以下是扫描一页手写作业的输出:
复印机似乎是随机选择是将每个符号二值化(上图中的X)还是转换成笨拙的JPG图像(上图中的平方根符号)。不用说,我们可以做得更好。
摘要
我们从学生笔记的可爱扫描开始,如下所示:
此原始PNG图像以300DPI的分辨率扫描,其大小约为7.2MB。在转换为质量级别为85的JPG图像后,其大小约为790KB(注2)。因为扫描的PDF格式只是PNG或JPG的包装容器,所以我们不期望图像转换成PDF后文件大小会减小。况且每页800KB也很大。考虑到加载时间,每页100KB左右(注3)最合适。
虽然这个学生做的笔记很工整,但是扫描出来的图像看起来还是有点乱(这不能怪她)。反面写了很多,或隐或显。与背景为单一颜色的情况相比,在反面书写不仅分散了观看者的注意力,而且不利于JPG和PNG编码器压缩。
下面是我的noteshrink.py程序输出的样子:
这是一个比较小的PNG文件,只有121KB左右。输出的图像不仅更小,而且更清晰。
过程和彩色图像基础
以下是生成上述紧凑和干净图像的处理步骤:
1.确定原始扫描图像的背景颜色。
2.通过设定不同于背景颜色的阈值来分离图像的前景。
3.在前景中选择少量“渲染色”,然后将原图转换为索引色PNG图像。
在深入介绍上述每个步骤之前,回顾一下彩色图像的数字存储是有帮助的。因为人眼有三种类型的色敏细胞,所以我们可以通过组合不同强度的红、绿、蓝光来重现每种颜色(注4)。结果是每种颜色对应RGB颜色空间中的一个三维点,如下所示(注5):
虽然实向量空间允许无限连续的不同像素光强,但我们需要离散化颜色值进行数字存储。通常,为红色、绿色和蓝色分配8位存储空间。无论如何,将图像中的颜色映射到三维空间中的一个点上,是一种强有力的分析方法,在深入讨论以上三个步骤时,你会清楚地看到这一点。
确定背景颜色
因为页面的大部分区域没有手写或水平线,所以我们可以假设纸张颜色是扫描图像中最常见的颜色。如果扫描仪总是用相同的RGB三进制值呈现空白,问题就简单了。不幸的是,事实并非如此。扫描的颜色值会受到灰尘斑点、玻璃上的污渍、纸张本身不同部分的颜色差异、光传感器的噪声和其他因素的影响。所以现实情况是,“纸张颜色”可能是成千上万个不同的RGB值。
原扫描图像为2081X2531,共5267011像素。虽然我们可以检查所有像素,但只检查输入图像中的代表性样本会更快。默认情况下,noteshrink.py程序只对5%的像素进行采样(这对于300DPI的扫描来说非常好)。现在,让我们来看看在原始扫描下随机抽取的样本。
10000像素样本:
虽然上图和原始扫描图一点都不像3354,上面也没有——的字样,但是两张图的颜色分布大致相同。这两张图片一般为灰白色,带有一些红色、蓝色和灰色像素。下图同样是10000个像素,按亮度排序(像素的R、G、B值之和):
从上图来看,底部80-90%的地方好像都是一样的颜色。不过仔细看还是能发现色差的。其实上图中出现频率最高的颜色,其RGB值为(240,240,242),在10000个样本中只出现了226次,不到总像素的3%。
由于众数的比例在样本总数中只占很小的比例,所以要质疑它对图像颜色分布描述的可靠性。如果我们在找到模式之前减少颜色深度,我们可以更方便地找到页面的背景颜色。下图显示了每个通道从8位减少到4位的情况:
现在出现频率最高的颜色的RGB值为(224,224,224),在总样本像素中出现了3,623次(36%)。本质上,我们通过降低色深,让相近的颜色变成相同的颜色,这样也更容易找到数据中的峰值点(注6)。
这里在可靠性和准确性之间做了一个平衡:浅色深度更有利于找到颜色分布的中值,深色深度更准确。最后,我使用每通道6位来确定背景颜色,这似乎很好地平衡了以上两点。
分离前景色
一旦我们找到了背景颜色,我们就可以根据每个像素的颜色相似性对图像进行二值化。计算两种颜色相似度的一种自然方法是根据颜色的RGB空间计算它们的疯狂茉莉距离;然而,这种简单的方法不能很好地分离下列颜色:
下表显示了上述颜色及其与背景色的疯狂茉莉距离:
可以看到,深灰色,也就是应该归类为背景色的背面字迹的颜色,疯狂的茉莉距离大于应该归类为前景的粉色。任何能把粉色归类为前景的阈值也会把背面的字迹归类为前景。
我们可以通过将颜色从RGB空间映射到HSV空间来解决这个问题。HSV空间将RGB空间的立方体形状扭曲为圆柱体形状,如下节所示(注7):
HSV圆柱体的特点是从里到外,从下到上有一个彩色的圆圈。色相H指的是圆上的角度。圆柱体的中心线从底部的黑色到顶部的白色,中间逐渐过度的灰色。整条线s的饱和度为0。而整个圆柱体圆弧外表面的饱和度是1,不考虑色调。最后,亮度V是指一种颜色的总亮度,从圆柱体底部的黑色到圆柱体顶部的白色。
现在考虑几种在RGB空间很难区分的颜色。这次,检查它们在HSV空间中的V和S值:
你可以看到,白色,黑色和灰色在亮度V上有很大的不同,但具有相似的低饱和度S,至少现在对于红色和粉红色来说是这样。利用HSV提供的信息,我们可以通过以下规则成功区分一个像素是否是前景:
a、亮度V比背景色大0.3以上,或
b,饱和度S比背景色大0.2以上的颜色
前一个条件区分黑色笔迹,后一个条件区分红色笔迹和粉红色笔迹。这两种情况都有效地排除了灰背笔迹,不同的图像可能需要设置不同的S/V阈值。详见结果部分的详细介绍。
选择一组渲染颜色。
一旦我们把前景分开,我们就只有一些颜色对应纸上的笔迹了。让我们想象一下这些颜色。然而,这些颜色并不被视为一组像素,而是RGB颜色空间中的一些3D点。结果的散点图看起来有点“厚”,有几个色带:
上图是three.js生成的交互式3D图片(此翻译呈现为动图)。
现在的任务是将原始的24位每像素图像转换成具有少量代表色(这里是8种)的索引彩色图像。这样有两个效果:第一,渲染一种颜色只需要3位(因为8等于2的三次方),减少了文件大小;第二,使结果图像的颜色更加一致,因为相似的颜色很可能在结果图像中由相同的颜色呈现。
为了完成这项任务,我们使用了一种数据驱动的方法,该方法利用了上图中的“bulky”属性。选择上图中颜色簇中心对应的颜色,就可以得到一组比较准确的代表色。技术上,我们要用聚类分析来解决一个颜色量化问题(这个问题本身就是矢量量化问题的特例)。
我选择的解决这个问题的算法是K-average算法。一般来说,就是寻找一组中心点,使得周围点到最近中心点的平均距离最小。下图是在上图(注8)中选择7个集群(即7个中心点)时得到的结果:
在此图中,带有黑色外壳的点表示前景色的采样点,彩色线将这些点连接到最近的中心点。当整个原始图像转换为索引彩色图像时,每个以前的景点将被其最近的中心点所取代。最后,外圆表示到中心点的最远距离。
汽笛和铃声
除了设置亮度V和饱和度S的阈值,noteshrink.py程序还有其他几个特性。默认情况下,该程序将通过将颜色的最大和最小强度值重置为0到255来增加最终调色板中颜色的亮度和对比度。如果没有这种调整,上面图像的8色调色板看起来会像这样:
调整后的调色板更加生动:
该计划也有一个选项,强制背景颜色变成白色后,隔离前景。为了进一步减小PNG图片的大小,noteshrink.py程序可以自动调用optipng、pngcrush、pngquant等PNG优化工具。
最后,程序使用ImageMagick的转换工具将几幅图像合并成一个PDF文件,就像这个PDF文件一样。另外,noteshrink.py会根据输入的文件名自动排序(使用数字作为关键字,而不是像shell中的globbing那样按字母顺序排序)。当一心一意、傻傻的扫描仪(注9)输出的文件名像扫描9.png、扫描10.png时,最好按照数字大小排序。
结果
下面是几个程序输出的比较图。第一个(此处为pdf文件)在默认阈值设置下看起来不错:
以下是颜色集群的可视化结果:
下一个例子(此处为PDF文件)要求将饱和度阈值降低到0.045,因为下面的蓝灰色线非常浅。
这是彩色聚类图:
最后是一个从工程图纸扫描的例子(这里是pdf文件),这里,我把亮度V阈值设置为0.05,因为背景色和线条的对比度很低:
颜色聚类图如下:
四个PDF文件总共788KB,每页大约130KB。
结论和进一步的工作。
我很高兴为我的课程网站编写一个实用程序来处理手写笔记。此外,我也很享受这篇文章的写作,特别是在写作时,我被鼓励改善维基百科中颜色量化的2D可视化部分。并且最后学会了three.js(很有意思,我再用这个)。
如果有一天我重访这个项目,我会尝试其他量化方案。这周我的一个想法是用谱聚类来处理一组颜色样本的最近邻图。我以为这是一个全新的想法,结果2012年的一篇论文已经提出了这个想法。是啊,好吧。
你也可以尝试用最大期望算法来构造一个高斯混合模型来描述颜色分布。——我不确定以前是否有人做过。其他有趣的想法是尝试“感知一致”的颜色空间,如L*a*b*来形成集群。或者尝试自动确定给定图像的最佳聚类数。
另一方面,我还有很多播客项目要做,所以我会暂时搁置这个项目,请你查看noteshrink.py的github库
1.我的学生乌苏拉莫纳汉和约翰拉金已经慷慨地允许在这里使用手写的文字记录。
2.注意,为了加载速度,这张图其实已经缩小到150DPI了。
3.注意:我们的复印机在限制PDF文件的大小方面做得很好。这种类型的文件每页大约减少50-75KB。
4.这是加法三原色:红、绿、蓝。你的初级美术老师可能会告诉你,三原色是红黄蓝,这是不正确的。确实有减色法原色,
它们是青色、黄色和品红色。加色原色与光线(显示器发出的光线)的组合有关,减色原色与墨水和染料的组合有关。
5.笔记。图片由维基媒体用户Maklaan提供,许可协议为CC BY-SA 3.0。
6.请注意,查看维基百科文章直方图文章,了解为什么增加“带宽”是有效的。
7.笔记。图片由维基媒体用户SharkD提供,许可协议为CC BY-SA 3.0。
8.为什么k=7而不是8?因为在最终的图像中,我们只需要8种颜色,背景色已经占了一种。
9.注意,没错,我在看你,Mac OS的图像捕捉。
英语原文:https://mzucker.github.io/2016/09/20/noteshrink.html
译者:yuezy3
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。