推特图像编码挑战

如果一张图片值1000个单词,那么在140个字符中你能容纳多少图片?

伙计们,就是这样!赏金的最后期限到了,经过一番艰难的思考,我决定Boojum的条目勉强超过萨姆·霍瑟瓦尔的。一旦我有机会把它们写下来,我会张贴更详细的笔记。当然,每个人都应该自由地继续提交解决方案,并改进解决方案以供人们投票。感谢所有提交和参赛的人;我都很喜欢。这次跑步对我来说很有趣,我希望对参赛者和观众来说都很有趣。

我看到这篇有趣的文章在尝试将图片压缩到Twitter评论中,许多人在那个线程(和Reddit上的帖子)对不同的方法提出了建议。所以,我认为这将是一个很好的编码挑战;让人们把他们的钱放在他们的嘴巴上,并展示他们关于编码的想法如何在有限的空间内带来更多细节。

我向您提出一个通用系统,将图像编码为140个字符的Twitter消息,然后再将它们解码为图像。您可以使用Unicode字符,因此每个字符可以获得8位以上的字节。然而,即使允许使用Unicode字符,也需要将图像压缩到非常小的空间;这肯定是一种有损压缩,因此必须对每个结果看起来有多好进行主观判断。

下面是原始作者Quasimondo从他的编码中得到的结果(图像是在创作共用署名-非商业性许可下授权的): 蒙娜丽莎

.

你能做得更好吗?

规则

  1. 你的程序必须有两种模式:编码解码
  2. <李>当# EYZ0:
    1. 您的程序必须以您选择的任何合理的光栅图形格式作为输入。我们认为ImageMagick支持的任何光栅格式都是合理的。
    2. 你的程序必须输出一个可以用140或更少的Unicode码位表示的消息;在U+0000 - U+10FFFF范围内的140个代码点,不包括非字符(U+FFFEU+FFFFU+U+10FFFF5FFFEU+U+10FFFF5FFFF,其中U+10FFFF5是1 - 10十六进制,范围U+10FFFF0 - U+10FFFF1)和代理代码点(U+10FFFF2 - U+10FFFF3)。它可以以您选择的任何合理编码输出;U+10FFFF8支持的任何编码都是合理的,平台原生编码或本地编码可能是一个不错的选择。详见U+10FFFF9。
    3. 李< / ol > < / > <李>当# EYZ0:
      1. 您的程序应该将编码模式的输出作为输入。
      2. 你的程序必须输出你选择的任何合理的格式的图像,如上所定义的,虽然输出矢量格式也是可以的。
      3. 图像输出应该是输入图像的近似值;越接近输入图像越好。
      4. 译码过程除了上述指定的输出外,不能访问编码过程的任何其他输出;也就是说,你不能把图像上传到某个地方,然后输出URL供解码过程下载,或者类似的傻事。
      5. 李< / ol > < / >
      6. 为了用户界面的一致性,你的程序必须如下所示:

        1. 您的程序必须是一个脚本,可以在平台上使用适当的解释器设置为可执行文件,或者是一个可以编译为可执行文件的程序。
        2. 您的程序必须将encodedecode作为第一个参数来设置模式。
        3. 你的程序必须以以下一种或多种方式获取输入(如果你实现了接受文件名的方式,如果文件名缺失,你也可以从stdin和stdout中读写):

          1. 从标准输入和在标准输出输出。

            my-program encode <input.png >output.txt
            my-program decode <output.txt >output.png
            
          2. Take input from a file named in the second argument, and produce output in the file named in the third.

            my-program encode input.png output.txt
            my-program decode output.txt output.png
            
      7. For your solution, please post:
        1. Your code, in full, and/or a link to it hosted elsewhere (if it's very long, or requires many files to compile, or something).
        2. An explanation of how it works, if it's not immediately obvious from the code or if the code is long and people will be interested in a summary.
        3. An example image, with the original image, the text it compresses down to, and the decoded image.
        4. If you are building on an idea that someone else had, please attribute them. It's OK to try to do a refinement of someone else's idea, but you must attribute them.

      Guidelines

      These are basically rules that may be broken, suggestions, or scoring criteria:

      1. Aesthetics are important. I'll be judging, and suggest that other people judge, based on:
        1. How good the output image looks, and how much it looks like the original.
        2. How nice the text looks. Completely random gobbledigook is OK if you have a really clever compression scheme, but I also want to see answers that turn images into mutli-lingual poems, or something clever like that. Note that the author of the original solution decided to use only Chinese characters, since it looked nicer that way.
        3. Interesting code and clever algorithms are always good. I like short, to the point, and clear code, but really clever complicated algorithms are OK too as long as they produce good results.
      2. Speed is also important, though not as important as how good a job compressing the image you do. I'd rather have a program that can convert an image in a tenth of a second than something that will be running genetic algorithms for days on end.
      3. I will prefer shorter solutions to longer ones, as long as they are reasonably comparable in quality; conciseness is a virtue.
      4. Your program should be implemented in a language that has a freely-available implementation on Mac OS X, Linux, or Windows. I'd like to be able to run the programs, but if you have a great solution that only runs under MATLAB or something, that's fine.
      5. Your program should be as general as possible; it should work for as many different images as possible, though some may produce better results than others. In particular:
        1. Having a few images built into the program that it matches and writes a reference to, and then produces the matching image upon decoding, is fairly lame and will only cover a few images.
        2. A program that can take images of simple, flat, geometric shapes and decompose them into some vector primitive is pretty nifty, but if it fails on images beyond a certain complexity it is probably insufficiently general.
        3. A program that can only take images of a particular fixed aspect ratio but does a good job with them would also be OK, but not ideal.
        4. You may find that a black and white image can get more information into a smaller space than a color image. On the other hand, that may limit the types of image it's applicable to; faces come out fine in black and white, but abstract designs may not fare so well.
        5. It is perfectly fine if the output image is smaller than the input, while being roughly the same proportion. It's OK if you have to scale the image up to compare it to the original; what's important is how it looks.
      6. Your program should produce output that could actually go through Twitter and come out unscathed. This is only a guideline rather than a rule, since I couldn't find any documentation on the precise set of characters supported, but you should probably avoid control characters, funky invisible combining characters, private use characters, and the like.

      Scoring rubric

      As a general guide to how I will be ranking solutions when choosing my accepted solution, lets say that I'll probably be evaluating solutions on a 25 point scale (this is very rough, and I won't be scoring anything directly, just using this as a basic guideline):

      • 15 points for how well the encoding scheme reproduces a wide range of input images. This is a subjective, aesthetic judgement
        • 0 means that it doesn't work at all, it gives the same image back every time, or something
        • 5 means that it can encode a few images, though the decoded version looks ugly and it may not work at all on more complicated images
        • 10 means that it works on a wide range of images, and produces pleasant looking images which may occasionally be distinguishable
        • 15 means that it produces perfect replicas of some images, and even for larger and more complex images, gives something that is recognizable. Or, perhaps it does not make images that are quite recognizable, but produces beautiful images that are clearly derived from the original.
      • 3 points for clever use of the Unicode character set
        • 0 points for simply using the entire set of allowed characters
        • 1 point for using a limited set of characters that are safe for transfer over Twitter or in a wider variety of situations
        • 2 points for using a thematic subset of characters, such as only Han ideographs or only right-to-left characters
        • 3 points for doing something really neat, like generating readable text or using characters that look like the image in question
      • 3 points for clever algorithmic approaches and code style
        • 0 points for something that is 1000 lines of code only to scale the image down, treat it as 1 bit per pixel, and base64 encode that
        • 1 point for something that uses a standard encoding technique and is well written and brief
        • 2 points for something that introduces a relatively novel encoding technique, or that is surprisingly short and clean
        • 3 points for a one liner that actually produces good results, or something that breaks new ground in graphics encoding (if this seems like a low number of points for breaking new ground, remember that a result this good will likely have a high score for aesthetics as well)
      • 2 points for speed. All else being equal, faster is better, but the above criteria are all more important than speed
      • 1 point for running on free (open source) software, because I prefer free software (note that C# will still be eligible for this point as long as it runs on Mono, likewise MATLAB code would be eligible if it runs on GNU Octave)
      • 1 point for actually following all of the rules. These rules have gotten a bit big and complicated, so I'll probably accept otherwise good answers that get one small detail wrong, but I will give an extra point to any solution that does actually follow all of the rules

      Reference images

      Some folks have asked for some reference images. Here are a few reference images that you can try; smaller versions are embedded here, they all link to larger versions of the image if you need those:

      Lena Mona Lisa Cornell Box StackOverflow Logo

      Prize

      I am offering a 500 rep bounty (plus the 50 that StackOverflow kicks in) for the solution that I like the best, based on the above criteria. Of course, I encourage everyone else to vote on their favorite solutions here as well.

      Note on deadline

      This contest will run until the bounty runs out, about 6 PM on Saturday, May 30. I can't say the precise time it will end; it may be anywhere from 5 to 7 PM. I will guarantee that I'll look at all entries submitted by 2 PM, and I will do my best to look at all entries submitted by 4 PM; if solutions are submitted after that, I may not have a chance to give them a fair look before I have to make my decision. Also, the earlier you submit, the more chance you will have for voting to be able to help me pick the best solution, so try and submit earlier rather than right at the deadline.

      Unicode notes

      There has also been some confusion on exactly what Unicode characters are allowed. The range of possible Unicode code points is U+0000 to U+10FFFF. There are some code points which are never valid to use as Unicode characters in any open interchange of data; these are the noncharacters and the surrogate code points. Noncharacters are defined in the Unidode Standard 5.1.0 section 16.7 as the values U+FFFE, U+FFFF, U+nFFFE, U+nFFFF where n is 110 hexadecimal, and the range U+FDD0U+FDEF. These values are intended to be used for application-specific internal usage, and conforming applications may strip these characters out of text processed by them. Surrogate code points, defined in the Unicode Standard 5.1.0 section 3.8 as U+D800U+DFFF, are used for encoding characters beyond the Basic Multilingual Plane in UTF-16; thus, it is impossible to represent these code points directly in the UTF-16 encoding, and it is invalid to encode them in any other encoding. Thus, for the purpose of this contest, I will allow any program which encodes images into a sequence of no more than 140 Unicode code points from the range U+0000U+10FFFF, excluding all noncharacters and surrogate pairs as defined above.

      I will prefer solutions that use only assigned characters, and even better ones that use clever subsets of assigned characters or do something interesting with the character set they use. For a list of assigned characters, see the Unicode Character Database; note that some characters are listed directly, while some are listed only as the start and end of a range. Also note that surrogate code points are listed in the database, but forbidden as mentioned above. If you would like to take advantage of certain properties of characters for making the text you output more interesting, there are a variety of databases of character information available, such as a list of named code blocks and various character properties.

      Since Twitter does not specify the exact character set they support, I will be lenient about solutions which do not actually work with Twitter because certain characters count extra or certain characters are stripped. It is preferred but not required that all encoded outputs should be able to be transferred unharmed via Twitter or another microblogging service such as identi.ca. I have seen some documentation stating that Twitter entity-encodes <, >, and &, and thus counts those as 4, 4, and 5 characters respectively, but I have not tested that out myself, and their JavaScript character counter doesn't seem to count them that way.

      Tips & Links

      • The definition of valid Unicode characters in the rules is a bit complicated. Choosing a single block of characters, such as CJK Unified Ideographs (U+4E00–U+9FCF) may be easier.
      • You may use existing image libraries, like ImageMagick or Python Imaging Library, for your image manipulation.
      • If you need some help understanding the Unicode character set and its various encodings, see this quick guide or this detailed FAQ on UTF-8 in Linux and Unix.
      • The earlier you get your solution in, the more time I (and other people voting) will have to look at it. You can edit your solution if you improve it; I'll base my bounty on the most recent version when I take my last look through the solutions.
      • If you want an easy image format to parse and write (and don't want to just use an existing format), I'd suggest using the PPM format. It's a text based format that's very easy to work with, and you can use ImageMagick to convert to and from it.
97662 次浏览

我的解决方案概述如下:

    我首先计算可以放入140 utf8字符的最大原始数据量。
    • (我假设utf8,这是最初的网站声称twitter存储消息的地方。这与上面的问题语句不同,上面的问题语句要求utf16。)
    • 使用这是utf8常见问题,我计算出在单个utf8字符中可以编码的最大比特数是31位。为了做到这一点,我将使用U-04000000 - U-7FFFFFFF范围内的所有字符。(1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx,有31个x,因此我可以编码31位)。
    • 31位乘以140位等于4340位。除以8得到524.5,四舍五入到542个字节
    • (如果我们限制自己使用utf16,那么每个字符只能存储2个字节,这将等于280字节)。
    • 李< / ul > < / >
    • 使用标准jpg压缩图像。
      • 将图像大小调整为大约50x50px,然后尝试在不同的压缩级别上压缩它,直到你有一个尽可能接近542字节的图像,而不会超过。
      • 这是一个例子的蒙娜丽莎压缩到536字节。
      • 李< / ul > < / >
      • 将压缩图像的原始位编码为utf-8字符。
        • 将以下字节中的每个x替换为图像中的位:1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
        • 这部分可能是需要编写大部分代码的部分,因为目前还没有任何东西可以做到这一点。
        • 李< / ul > < / >

我知道你们要的是代码,但我不想花时间写代码。我想一个有效的设计至少可以激励其他人编写代码。

我认为我提出的解决方案的主要好处是,它重用了尽可能多的现有技术。尝试编写一个好的压缩算法可能很有趣,但肯定会有更好的算法,很可能是由拥有高等数学学位的人编写的。

另一个重要的注意事项是,如果决定utf16是首选编码,那么这个解决方案就会失败。当压缩到280字节时,jpeg就不能正常工作了。不过,对于这个特定的问题语句,可能有比jpg更好的压缩算法。

Roger Alsing写的这个遗传算法有一个很好的压缩比,代价是很长的压缩时间。得到的顶点向量可以使用有损或无损算法进一步压缩。

http://rogeralsing.com/2008/12/07/genetic-programming-evolution-of-mona-lisa/

这将是一个很有趣的程序,但我还是算了。

在最初的挑战中,大小限制的定义是,如果你将文本粘贴到Twitter的文本框中,并按下“更新”键,Twitter仍然允许你发送的内容。正如一些人正确地注意到的那样,这与你用手机发送的短信不同。

没有明确提到的是(但我个人的规则是),你应该能够在浏览器中选择tweet消息,将其复制到剪贴板,并将其粘贴到解码器的文本输入字段中,以便它可以显示。当然,你也可以自由地将消息保存为文本文件并将其读入,或者编写一个工具来访问Twitter API并过滤掉任何看起来像图像代码的消息(特殊标记)。# EYZ0 # EYZ0)。但规则是,信息必须通过Twitter才能被允许解码。

祝你好运,这350个字节——我怀疑你能不能利用它们。

发布单色或灰度图像应该提高图像的大小,可以编码到那个空间,因为你不关心颜色。

可能会增加上传三张图像的挑战,当重新组合时,你会得到一张全彩图像,同时在每张单独的图像中仍然保持单色版本。

在上面添加一些压缩,它可以开始看起来可行…

不错! !你们引起了我的兴趣。今天剩下的时间都没有工作要做。

我的完整解决方案可以在< a href = " http://caca.zoy.org/wiki/img2twit " > http://caca.zoy.org/wiki/img2twit找到。它具有以下特点:

  • 合理的压缩时间(高质量1分钟左右)
  • 快速解压(几分之一秒)
  • 保持原始图像大小(不仅仅是纵横比)
  • 体面的重建质量(IMHO)
  • 消息长度和字符集(ASCII, CJK,符号)可以在运行时选择
  • 消息长度和字符集在解压时自动检测
  • 非常有效的信息包装

< a href = " http://caca.zoy.org/raw-attachment/wiki/img2twit/so-logo.png " > http://caca.zoy.org/raw-attachment/wiki/img2twit/so-logo.png # EYZ0 < / p >

蜥秓鋖筷聝诿缰偺腶漷庯祩皙靊谪獜岨幻寤厎趆脘搇梄踥桻理戂溥欇渹裏軱骿苸髙骟市簶璨粭浧鱉捕弫潮衍蚙瀹岚玧霫鏓蓕戲債鼶襋躻弯袮足庭侅旍凼飙驅據嘛掔倾诗籂阉嶹婻椿糢墤渽緛赐更儅棫武婩縑逡荨璙杯翉珸齸陁颗鳣憫擲舥攩寉鈶兓庭璱篂鰀乾丕耓庁錸努樀肝亖弜喆蝞躐葌熲谎蛪曟暙刍镶媏嘝驌慸盂氤缰殾譑

以下是对编码过程的粗略概述:

  • 可用的比特数根据所需的消息长度和可用的字符集计算
  • 源图像被分割成尽可能多的正方形单元,因为可用的位允许
  • 每个单元格都有固定数量的点(目前是2个),具有初始坐标和颜色值
  • 重复执行以下操作,直到满足质量条件:
    • 点是随机选择的
    • 在这个点上随机执行一个操作(将它移动到它的单元格内,改变它的颜色)
    • 如果生成的图像(参见下面的解码过程)更接近源图像,则该操作将被保留
    • 李< / ul > < / >
    • 图像大小和点列表用UTF-8编码

    这是解码的过程:

    • 图像大小和点从UTF-8流中读取
    • 对于目标图像中的每个像素:
      • 计算自然邻居列表
      • 像素的最终颜色设置为其自然邻居颜色的加权平均值

    我认为这个程序最原始的部分是比特流。我没有打包位对齐的值(stream <<= shift; stream |= value),而是打包不在2的幂范围内的任意值(stream *= range; stream += value)。这需要大量的计算,当然也要慢得多,但当使用20902个主要CJK字符时,它给了我2009.18位而不是1960位(这是我可以在数据中添加的3个点)。当使用ASCII码时,我得到的是917.64位而不是840位。

    我决定放弃一种需要重型武器(角落检测、特征提取、颜色量化……)的初始图像计算方法,因为一开始我不确定它是否真的有用。现在我意识到收敛是缓慢的(1分钟是可以接受的,但它仍然很慢),我可能会尝试改善这一点。

    主拟合循环松散地受到直接二进制搜索抖动算法的启发(像素被随机交换或翻转,直到获得更好的半色调)。能量计算是一个简单的均方根距离,但我先对原始图像执行5x5的中值滤波。高斯模糊可能会更好地代表人眼的行为,但我不想失去锐利的边缘。我还决定不使用模拟退火或其他难以调优的方法,因为我没有几个月的时间来校准过程。因此,“quality”标志只是表示编码器结束前在每个点上执行的迭代次数。

    < a href = " http://caca.zoy.org/raw-attachment/wiki/img2twit/Mona_Lisa_scaled.jpg " > http://caca.zoy.org/raw-attachment/wiki/img2twit/Mona_Lisa_scaled.jpg # EYZ0 < / p >

    苉憗揣嶕繠剳腏篮濕茝霮墧蒆棌杚蓳縳樟赒肴飗噹砃燋任朓峂釰靂陴貜犟掝喗讄荛砙矺敨鷾瓔亨髎芟氲簵鸬嫤鉸俇激躙憮鄴甮槺骳佛愚猪駪惾嫥綖珏矯坼堭颽箽赭飉訥偁箝窂蹻熛漧衆橼愀航玴毡裋頢羔恺墎嬔鑹楄瑥鶼呍蕖抲鸝秓苾绒酯嵞脔婺污囉酼俵菛琪棺则辩曚鸸職銛蒝礭鱚蟺稿纡醾陴鳣尥蟀惘鋁髚忩祤脤养趯沅况

    尽管不是所有的图像都压缩得很好,但我对结果感到惊讶,我真的很想知道还有什么其他方法可以将图像压缩到250字节。

    我也有编码器状态的演变从一个随机的初始状态从“良好”的初始状态开始的小电影。

    编辑:这里是压缩方法与JPEG的比较。左边是james的536字节图片。在右边,蒙娜丽莎使用这里描述的方法压缩到534字节(这里提到的字节指的是数据字节,因此忽略了使用Unicode字符浪费的比特):

    < a href = " http://caca.zoy.org/raw-attachment/wiki/img2twit/minimona.jpg " > http://caca.zoy.org/raw-attachment/wiki/img2twit/minimona.jpg # EYZ0 < / p >

    编辑:刚刚用最新版本的图像替换了CJK文本。

存储一堆参考图像的想法很有趣。存储25Mb的样本图像,并让编码器尝试使用这些位来组成图像,这是错误的吗?对于这么小的管道,两端的机器必然要比通过的数据量大得多,那么25Mb的代码和1Mb的代码和24Mb的图像数据之间有什么区别呢?

(请注意,最初的指导方针排除了将输入限制为库中已经存在的图像-我不是这样建议的)。

图像文件和python源代码(版本1和2)

< >强版本1 这是我的第一次尝试。

我已经把SO标志降到300个字符几乎无损。我的技术使用转换到SVG矢量艺术,所以它在直线艺术上效果最好。它实际上是一个SVG压缩器,它仍然需要原始美术经过矢量化阶段。

对于我的第一次尝试,我使用了在线服务的PNG跟踪,然而有许多免费和非免费的工具可以处理这一部分,包括potrace(开源)。

以下是结果

< p > # EYZ0原创 解码SO Logo http://www.warriorhut.org/graphics/svg_to_unicode/so-logo-decoded.png编码解码后

# EYZ0: 300

时间:没有测量,但实际上是即时的(不包括矢量化/栅格化步骤)

下一阶段将为每个unicode字符嵌入4个符号(SVG路径点和命令)。目前,我的python构建没有广泛的字符支持UCS4,这限制了我的每个字符的分辨率。我还将最大范围限制在unicode保留范围0xD800的低端,然而,一旦我构建了允许字符的列表和一个过滤器来避免它们,理论上我可以将上面的logo所需的字符数量降低到70-100。

目前这种方法的一个局限性是输出大小不固定。它取决于向量化后的向量节点/点的数量。自动化这一限制将需要对图像进行像素化(这将消除向量的主要好处),或者在简化阶段重复运行路径,直到达到所需的节点数(这是我目前在Inkscape中手动执行的)。

版本2

更新: v2现在有资格参加比赛。变化:

  • 命令行控制输入/输出和调试
  • 使用XML解析器(lxml)来处理SVG而不是正则表达式
  • 每个unicode符号打包2个路径段
  • 文档和清理
  • 支持style="fill:color"和fill="color"
  • 文档宽度/高度打包成单个字符
  • 路径颜色包装成单个字符
  • 颜色压缩由 每次丢弃4位的颜色数据 然后通过十六进制转换将其包装成一个字符

# EYZ0: # EYZ1

几秒钟

V2解码http://www.warriorhut.org/graphics/svg_to_unicode/so-logo-decoded-v2.png编码解码后(版本2)

正如您所看到的,这次有一些人工制品。这不是方法的限制,而是我转换中的某个错误。当点超出0.0 - 127.0范围时,就会发生工件,我试图约束它们的尝试有好有坏。解决方案是简单地缩放图像,但我有问题缩放实际的点,而不是画板或组矩阵,我现在太累了。简而言之,如果你的点在支持的范围内,它通常是可行的。

我相信中间的扭结是由于一个手柄移动到另一边的手柄连接。基本上,这些点一开始就靠得太近了。在压缩源图像之前运行一个简化过滤器可以修复这个问题,并去除一些不必要的字符。

< p > # EYZ0: 这种方法适用于简单的对象,所以我需要一种方法来简化复杂的路径并减少噪音。我使用来完成这个任务。我曾经用Inkscape剔除了一些不必要的路径,但没有时间尝试自动化。我用Inkscape的“Simplify”函数做了一些svgs样例,以减少路径的数量

简化工作还可以,但它可能会很慢,因为有这么多路径。

# eyz0 # eyz1 # eyz2

thumbnails tracing http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_autotrace.png

这里有一些超低分辨率的照片。这些将更接近140个字符的限制,尽管一些聪明的路径压缩可能也需要。

groomed http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_groomed.png

trianglulated http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_triangulated.png

autotrace --output-format svg --output-file cornell_box.svg --despeckle-level 20 --color-count 64 cornell_box.png

上图:使用自动跟踪简化路径。

不幸的是,我的解析器不处理自动跟踪输出,所以我不知道有多少点在使用或简化到什么程度,遗憾的是,在截止日期之前没有时间写它。它比inkscape输出更容易解析。

以下并不是正式的提交,因为我的软件并没有针对指定的任务进行任何调整。DLI可以被描述为一个优化的通用有损图像编解码器。它是图像压缩的PSNR和MS-SSIM记录持有者,我想看看它在这个特定任务中的表现会很有趣。我使用提供的参考蒙娜丽莎图像,并将其缩小到100x150,然后使用DLI将其压缩到344字节。

蒙娜丽莎DLI http://i40.tinypic.com/2md5q4m.png

为了与JPEG和IMG2TWIT压缩样例进行比较,我也使用DLI将图像压缩到534字节。JPEG是536字节,IMG2TWIT是534字节。为了便于比较,图像被放大到大致相同的大小。左边是JPEG图像,中间是IMG2TWIT图像,右边是DLI图像。

比较http://i42.tinypic.com/302yjdg.png

DLI图像设法保留了一些面部特征,最著名的是著名的微笑:)。

好吧,这是我的:nanocrunch.cppCMakeLists.txt文件,使用CMake。来构建它。它依赖于魔法+ + ImageMagick API来进行大多数图像处理。它还需要GMP库用于字符串编码的大算术。

我基于分形图像压缩的解决方案,有一些独特的扭曲。基本思路是将图像缩小到50%,然后在各个方向上寻找与原始图像中不重叠的块相似的部分。它对这个搜索采取了非常强力的方法,但这只是让我更容易介绍我的修改。

第一个修改是,我的程序不仅考虑90度的旋转和翻转,还考虑45度的方向。每块多一个比特,但它极大地提高了图像质量。

另一件事是,为每个块的每个颜色组件存储对比度/亮度调整太昂贵了。相反,我存储了一个重度量化的颜色(调色板只有4 * 4 * 4 = 64种颜色),它只是以某种比例混合在一起。从数学上讲,这相当于对每种颜色进行可变亮度和恒定对比度的调整。不幸的是,这也意味着没有负对比来翻转颜色。

一旦计算出每个块的位置、方向和颜色,它就会将其编码为UTF-8字符串。首先,它生成一个非常大的bigum来表示块表中的数据和图像大小。这个方法类似于Sam Hocevar的解——一个基数随位置变化的大数。

然后它将其转换为可用字符集大小的基数。默认情况下,它充分使用指定的unicode字符集,减去小于、大于、&号、控件、组合以及代理和私有字符。虽然不漂亮,但很有效。您还可以注释掉默认表并选择可打印的7位ASCII(同样不包括<, >和&字符)或CJK统一表意文字。可用字符代码的表以一个运行长度存储,该运行长度由无效字符和有效字符的交替运行编码。

不管怎样,这里有一些图像和时间(在我的旧3.0GHz P4上测量的),并在上面描述的完整分配的unicode集中压缩为140个字符。总的来说,我对他们的表现相当满意。如果我有更多的时间来处理这个问题,我可能会尝试减少解压缩图像的块状。尽管如此,我认为对于极限压缩比来说,结果还是相当不错的。解压缩的图像有点印象派,但我发现它相对容易看到比特如何对应原始。

堆栈溢出标志(8.6s编码,7.9s解码,485字节):
http://i44.tinypic.com/2w7lok1.png

Lena (32.8s编码,13.0s解码,477字节):
# EYZ0 # EYZ1 < / p >

蒙娜丽莎(43.2秒编码,14.5秒解码,490字节):
# EYZ0 # EYZ1 < / p >

编辑:CJK统一字符

Sam在评论中问关于在CJK中使用这个。以下是从CJK统一字符集压缩到139个字符的《蒙娜丽莎》版本:

http://i43.tinypic.com/2yxgdfk.png 咏璘驞凄脒鵚据蛥鸂拗朐朖辿韩瀦魷歪痫栘璯緍脲蕜抱揎頻蓼債鑡嗞靊寞柮嚛嚵籥聚隤慛絖銓馿渫櫰矍昀鰛掾撄粂敽牙稉擎蔍螎葙峬覧絀蹔抆惫冧笻哜搀澐芯譶辍澮垝黟偞媄童竽梀韠镰猳閺狌而羶喙伆杇婣唆鐤諽鷍鴞駫搶毤埙誖萜愿旖鞰萗勹鈱哳垬濅鬒秀瞛洆认気狋異闥籴珵仾氙熜謋繴茴晋髭杍嚖熥勳縿餅珝爸擸萿< / p >

我使用的程序顶部的调优参数是:19,19,4,4,3,10,11,1000,1000。我还注释掉了number_assigned和codes的第一个定义,并取消注释掉了它们的最后一个定义,以选择CJK统一字符集。

以下是我解决这个问题的方法,我必须承认这是一个非常有趣的项目,它绝对超出了我的正常工作范围,给了我一些新的东西去学习。

我的基本想法如下:

  1. 向下采样图像灰度,这样总共有16个不同的阴影
  2. 在映像上执行RLE
  3. 将结果打包为UTF-16字符
  4. 对打包的结果执行RLE以删除任何重复字符

事实证明,这是有效的,但从下面的示例图像中可以看到,这只是在有限的范围内。就输出而言,下面是一个示例推文,特别是示例中显示的Lena图像。

乤乤万乐唂伂倂倁企儂2企倁3企倁2企伂8企伂3企伂5企倂倃伂倁3企儁企2伂倃5企倁3企倃4企倂企倁企伂2企伂5企倁企伂쥹皗鞹鐾륶䦽阹럆䧜椿籫릹靭욶옷뎷歩㰷歉䴗鑹㞳鞷㬼獴鏙돗鍴祳㭾뤶殞焻�乹Ꮛ靆䍼

正如你所看到的,我确实试着限制了字符集;然而,在存储图像颜色数据时,我遇到了这样做的问题。此外,这种编码方案也会浪费大量可以用于其他图像信息的数据位。

就运行时间而言,对于较小的图像,代码的运行速度非常快,对于所提供的示例图像大约为55ms,但对于较大的图像,时间确实会增加。对于512x512 Lena参考映像,运行时间为1182ms。我应该指出的是,代码本身并没有很好地优化性能(例如,所有内容都作为位图使用),所以在一些重构之后,时间可能会减少一些。

请随时为我提供任何建议,我可以做得更好或什么可能是错误的代码。运行时和示例输出的完整列表可以在以下位置找到:http://code-zen.info/twitterimage/

更新一个

我已经更新了压缩推文字符串时使用的RLE代码,以做一个基本的回顾,如果是这样,那么使用输出。这只适用于数字值对,但它确实保存了数据的几个字符。运行时间和图像质量大致相同,但推文往往更小一些。测试完成后我会在网站上更新图表。以下是一个推文字符串的例子,同样是莉娜的小版本:

乤乤万乐唂伂倂倁企儂2企倁3企倁ウ伂8企伂エ伂5企倂倃伂倁グ儁企2伂倃ガ倁ジ倃4企倂企倁企伂ツ伂ス倁企伂쥹皗鞹鐾륶䦽阹럆䧜椿籫릹靭욶옷뎷歩㰷歉䴗鑹㞳鞷㬼獴鏙돗鍴祳㭾뤶殞焻�乹Ꮛ靆䍼

更新两个

另一个小更新,但我修改了代码,将颜色阴影包装成三组而不是四组,这使用了更多的空间,但除非我遗漏了一些东西,这应该意味着“奇数”字符不再出现在颜色数据所在的地方。此外,我更新了压缩,使它现在可以作用于整个字符串,而不仅仅是颜色计数块。我仍在测试运行时间,但它们似乎在名义上有所改进;然而,图像质量仍然是一样的。以下是最新版本的Lena推文:

2乤万乐唂伂倂倁企儂2企倁3企倁ウ伂8企伂エ伂5企倂倃伂倁グ儁企2伂倃ガ倁ジ倃4企倂企倁企伂ツ伂ス倁企伂坹坼坶坻刾啩容力吹婩媷劝圿咶坼妛啭奩嗆婣冷咛啫凃奉佶坍均喳女媗决兴宗喓夽兴唹屹冷圶埫奫唓坤喝奎似商嗉乃

# eyz0 # eyz1 # eyz2 # eyz3

愚蠢的想法,但sha1(my_image)将导致任何图像的“完美”表示(忽略碰撞)。显而易见的问题是解码过程需要大量的暴力。

1位单色会更容易一些。每个像素变成1或0,所以对于100*100像素的图像,您将有1000位数据。由于SHA1哈希值是41个字符,我们可以在一条消息中放入三个字符,只需要强力使用两组3333位和一组3334位(尽管这可能仍然是不合理的)。

这不太实际。即使是固定长度的1位100*100px图像。,假设我没有算错,49995000个组合,或者16661667个组合。

def fact(maxu):
ttl=1
for i in range(1,maxu+1):
ttl=ttl*i
return ttl


def combi(setsize, length):
return fact(length) / (fact(setsize)*fact(length-setsize))


print (combi(2, 3333)*2) + combi(2, 3334)
# 16661667L
print combi(2, 10000)
# 49995000L

这里的压缩效果很好。

http://www.intuac.com/userport/john/apt/

http://img86.imageshack.us/img86/4169/imagey.jpg http://img86.imageshack.us/img86/4169/imagey.jpg

我使用以下批处理文件:

capt mona-lisa-large.pnm out.cc 20
dapt out.cc image.pnm
Pause

结果文件大小为559字节。

关于这个挑战的编码/解码部分。 base16b.org是我试图指定一种标准方法,用于在更高的Unicode平面中安全有效地编码二进制数据

一些特点:

  • 只使用Unicode的私有用户区域
  • 编码高达17位每个字符;几乎是Base64的三倍
  • 提供了encode/decode的参考Javascript实现
  • 包括一些示例编码,包括Twitter和Wordpress

对不起,这个答案对于最初的比赛来说太晚了。我独立于这篇文章开始了这个项目,这是我在中途发现的。

好吧,我来晚了,但我还是完成了我的项目。

这是一个玩具遗传算法,使用半透明的彩色圆圈来重建初始图像。

特点:

  • 纯粹的Lua。在Lua解释器运行的任何地方运行。
  • 使用netpbm P3格式
  • 附带一套全面的单元测试
  • 保留原始图像大小

Mis-feautres:

  • 在这样的空间限制下,它只保留初始图像的基本配色方案和少数特征的大致轮廓。
下面是一个代表Lena的例子: 犭楊谷杌蒝螦界匘玏扝匮俄归晃客猘摈硰划刀萕码摃斢嘁蜁嚎耂澹簜僨砠偑婊內團揕忈義倨襠凁梡岂掂戇耔攋斘眐奡萛狂昸箆亲嬎廙栃兡塅受橯恰应戞优猫僘瑩吱賾卣朸杈腠綍蝘猕屐稱悡詬來噩压罍尕熚帤厥虤嫐虲兙罨縨炘排叁抠堃從弅慌螎熰標宑簫柢橙拃丨蜊缩昔儻舭勵癳冂囤璟彔榕兠摈侑蒖孂埮槃姠璐哠眛嫡琠枀訜苄暬厇廩焛瀻严啘刱垫仔< / p >

original lena encoded lena

代码在bitbucket.org的Mercurial存储库中。看看http://bitbucket.org/tkadlubo/circles.lua

想法:你可以用字体作为调色板吗?尝试将图像分解为一系列向量,尝试用向量集的组合来描述它们(每个字符本质上是一组向量)。这是使用字体作为字典。我可以用l表示垂直线用-表示水平线?只是一个想法。