Desafio de codificação de imagem do Twitter [fechado]

597

Se uma imagem vale mais que 1000 palavras, quanto da imagem você pode caber em 140 caracteres?

Nota : É isso aí pessoal! Chegou o prazo da recompensa e, após algumas deliberações difíceis, decidi que a entrada de Boojum mal superava a de Sam Hocevar . Vou postar notas mais detalhadas assim que tiver a chance de escrevê-las. Obviamente, todos devem se sentir à vontade para continuar enviando soluções e aprimorando soluções para as pessoas votarem. Obrigado a todos que enviaram e inscrevem-se; Eu gostei de todos eles. Isso foi muito divertido para mim, e espero que tenha sido divertido tanto para os participantes quanto para os espectadores.

Me deparei com este post interessante sobre como tentar compactar imagens em um comentário no Twitter, e muitas pessoas nesse tópico (e um tópico no Reddit ) tinham sugestões sobre diferentes maneiras de fazer isso. Então, acho que seria um bom desafio de codificação; permita que as pessoas coloquem seu dinheiro onde estão, e mostre como suas idéias sobre codificação podem levar a mais detalhes no espaço limitado disponível.

Desafio você a criar um sistema de uso geral para codificar imagens em mensagens do Twitter com 140 caracteres e decodificá-las em uma imagem novamente. Você pode usar caracteres Unicode para obter mais de 8 bits por caractere. Mesmo permitindo caracteres Unicode, no entanto, você precisará compactar imagens em uma quantidade muito pequena de espaço; isso certamente será uma compactação com perdas e, portanto, terá que haver julgamentos subjetivos sobre a qualidade de cada resultado.

Aqui está o resultado que o autor original, Quasimondo , obteve de sua codificação (a imagem é licenciada sob uma licença Creative Commons Attribution-Noncommercial ): Monalisa

Você pode fazer melhor?

Regras

  1. Seu programa deve ter dois modos: codificação e decodificação .
  2. Ao codificar :
    1. Seu programa deve ter como entrada um gráfico em qualquer formato gráfico de varredura razoável de sua escolha. Diremos que qualquer formato raster suportado pelo ImageMagick conta como razoável.
    2. Seu programa deve gerar uma mensagem que possa ser representada em 140 ou menos pontos de código Unicode; 140 pontos de código no intervalo U+0000- U+10FFFF, excluindo não caracteres ( U+FFFE, U+FFFF, U+nFFFE , U+nFFFF , onde n é 1- 10hexadecimal, e a gama U+FDD0- U+FDEF) e pontos de código substituto ( U+D800- U+DFFF). Pode ser produzido em qualquer codificação razoável de sua escolha; qualquer codificação suportada pelo GNUiconv será considerada razoável, e a codificação nativa ou local de sua plataforma provavelmente será uma boa opção. Veja as notas Unicode abaixo para mais detalhes.
  3. Ao decodificar :
    1. Seu programa deve ter como entrada a saída do seu modo de codificação .
    2. Seu programa deve gerar uma imagem em qualquer formato razoável de sua escolha, conforme definido acima, embora os formatos vetoriais de saída também sejam aceitáveis.
    3. A saída da imagem deve ser uma aproximação da imagem de entrada; quanto mais perto você estiver da imagem de entrada, melhor.
    4. O processo de decodificação pode não ter acesso a nenhuma outra saída do processo de codificação além da saída especificada acima; ou seja, você não pode fazer upload da imagem em algum lugar e gerar o URL para o processo de decodificação baixar, ou algo parecido.
  4. Por uma questão de consistência na interface do usuário, seu programa deve se comportar da seguinte maneira:

    1. Seu programa deve ser um script que possa ser definido como executável em uma plataforma com o intérprete apropriado ou um programa que possa ser compilado em um executável.
    2. Seu programa deve tomar como seu primeiro argumento encodeou decodepara definir o modo.
    3. Seu programa deve receber entradas de uma ou mais das seguintes maneiras (se você implementar a que aceita nomes de arquivos, também poderá ler e gravar a partir de stdin e stdout se houver nomes ausentes):

      1. Capte a entrada da entrada padrão e produza saída com saída padrão.

        my-program encode <input.png >output.txt
        my-program decode <output.txt >output.png
        
      2. Pegue a entrada de um arquivo nomeado no segundo argumento e produza saída no arquivo nomeado no terceiro.

        my-program encode input.png output.txt
        my-program decode output.txt output.png
        
  5. Para sua solução, poste:
    1. Seu código, na íntegra, e / ou um link para ele hospedado em outro local (se for muito longo ou exigir muitos arquivos para compilar, ou algo assim).
    2. Uma explicação de como funciona, se não for imediatamente óbvio no código ou se o código for longo e as pessoas se interessarem em um resumo.
    3. Uma imagem de exemplo, com a imagem original, o texto compactado e a imagem decodificada.
    4. Se você está construindo uma ideia que alguém teve, atribua-a. Não há problema em tentar refinar a ideia de outra pessoa, mas você deve atribuí-la.

Diretrizes

Estas são basicamente regras que podem ser quebradas, sugestões ou critérios de pontuação:

  1. A estética é importante. Vou julgar e sugerir que outras pessoas julguem, com base em:
    1. Qual a aparência da imagem de saída e a aparência da original.
    2. Que bom o texto parece. O gobbledigook completamente aleatório é bom se você tiver um esquema de compactação realmente inteligente, mas também quero ver respostas que transformam imagens em poemas multilíngües ou algo assim. Observe que o autor da solução original decidiu usar apenas caracteres chineses, pois parecia melhor assim.
    3. Código interessante e algoritmos inteligentes são sempre bons. Gosto de códigos curtos, diretos e claros, mas algoritmos complicados muito inteligentes são bons demais desde que produzam bons resultados.
  2. A velocidade também é importante, embora não seja tão importante quanto a qualidade de um trabalho para compactar a imagem que você faz. Prefiro ter um programa que possa converter uma imagem em um décimo de segundo do que algo que estará executando algoritmos genéticos por dias a fio.
  3. Prefiro soluções mais curtas a soluções mais longas, desde que sejam razoavelmente comparáveis ​​em qualidade; concisão é uma virtude.
  4. Seu programa deve ser implementado em um idioma que tenha uma implementação disponível gratuitamente no Mac OS X, Linux ou Windows. Eu gostaria de poder executar os programas, mas se você tem uma ótima solução que roda apenas no MATLAB ou algo assim, tudo bem.
  5. Seu programa deve ser o mais geral possível; deve funcionar com tantas imagens diferentes quanto possível, embora algumas possam produzir melhores resultados do que outras. Em particular:
    1. Ter algumas imagens integradas no programa às quais corresponde e gravar uma referência e depois produz a imagem correspondente após a decodificação é bastante ruim e cobrirá apenas algumas imagens.
    2. Um programa que pode capturar imagens de formas simples, planas e geométricas e decompô-las em algum vetor primitivo é bastante bacana, mas se falhar nas imagens além de uma certa complexidade, provavelmente será insuficientemente geral.
    3. Um programa que só pode capturar imagens de uma determinada proporção fixa, mas faz um bom trabalho com elas também seria bom, mas não ideal.
    4. Você pode achar que uma imagem em preto e branco pode obter mais informações em um espaço menor que uma imagem colorida. Por outro lado, isso pode limitar os tipos de imagem aos quais é aplicável; os rostos saem bem em preto e branco, mas os desenhos abstratos podem não se sair tão bem.
    5. É perfeitamente adequado se a imagem de saída for menor que a entrada, enquanto estiver aproximadamente na mesma proporção. Tudo bem se você precisar ampliar a imagem para compará-la ao original; o importante é como fica.
  6. Seu programa deve produzir resultados que possam realmente passar pelo Twitter e sair ilesos. Isso é apenas uma diretriz e não uma regra, já que não consegui encontrar nenhuma documentação sobre o conjunto preciso de caracteres suportados, mas você provavelmente deve evitar caracteres de controle, caracteres combinados invisíveis e funky, caracteres de uso privado e similares.

Rubrica de pontuação

Como um guia geral de como classificarei as soluções ao escolher minha solução aceita, digamos que provavelmente avaliarei soluções em uma escala de 25 pontos (isso é muito difícil e não pontuarei nada diretamente, apenas usando como orientação básica):

  • 15 pontos sobre o quão bem o esquema de codificação reproduz uma ampla gama de imagens de entrada. Este é um julgamento subjetivo, estético
    • 0 significa que não funciona, devolve a mesma imagem sempre, ou algo assim
    • 5 significa que ele pode codificar algumas imagens, embora a versão decodificada pareça feia e possa não funcionar em imagens mais complicadas
    • 10 significa que ele funciona em uma ampla variedade de imagens e produz imagens de aparência agradável que podem ocasionalmente ser distinguíveis
    • 15 significa que produz réplicas perfeitas de algumas imagens e, mesmo para imagens maiores e mais complexas, fornece algo que é reconhecível. Ou talvez não faça imagens que sejam bastante reconhecíveis, mas produz imagens bonitas que são claramente derivadas do original.
  • 3 pontos para o uso inteligente do conjunto de caracteres Unicode
    • 0 pontos por simplesmente usar todo o conjunto de caracteres permitidos
    • 1 ponto para usar um conjunto limitado de caracteres que são seguros para transferência pelo Twitter ou em uma variedade maior de situações
    • 2 pontos para usar um subconjunto temático de caracteres, como apenas ideogramas Han ou apenas caracteres da direita para a esquerda
    • 3 pontos para fazer algo realmente interessante, como gerar texto legível ou usar caracteres que se parecem com a imagem em questão
  • 3 pontos para abordagens algorítmicas inteligentes e estilo de código
    • 0 pontos para algo que é de 1000 linhas de código apenas para reduzir a imagem, tratá-la como 1 bit por pixel e codificar base64 que
    • 1 ponto para algo que usa uma técnica de codificação padrão e é bem escrito e breve
    • 2 pontos para algo que introduz uma técnica de codificação relativamente nova ou que é surpreendentemente curta e limpa
    • 3 pontos para um liner que realmente produz bons resultados, ou algo que abre novos caminhos na codificação gráfica (se isso parecer um número baixo de pontos para abrir novos caminhos, lembre-se de que um resultado desse bom provavelmente terá uma pontuação alta em estética também)
  • 2 pontos por velocidade. Tudo o resto é igual, mais rápido é melhor, mas os critérios acima são todos mais importantes que a velocidade
  • 1 ponto para execução no software livre (código aberto), porque eu prefiro o software livre (observe que o C # ainda será elegível para esse ponto enquanto for executado no Mono, da mesma forma o código MATLAB seria elegível se for executado no GNU Octave)
  • 1 ponto para realmente seguir todas as regras. Essas regras ficaram um pouco grandes e complicadas, então provavelmente aceitarei boas respostas que apresentem um pequeno detalhe errado, mas darei um ponto extra a qualquer solução que realmente siga todas as regras

Imagens de referência

Algumas pessoas pediram algumas imagens de referência. Aqui estão algumas imagens de referência que você pode tentar; versões menores são incorporadas aqui, todas elas se vinculam a versões maiores da imagem, se você precisar delas:

Lena Monalisa Cornell Box Logotipo StackOverflow

Prêmio

Estou oferecendo uma recompensa de 500 representantes (mais os 50 que o StackOverflow oferece ) para a solução que eu mais gosto, com base nos critérios acima. Obviamente, incentivo todos os outros a votarem em suas soluções favoritas aqui também.

Nota sobre prazo

Este concurso será realizado até que a recompensa acabe, cerca das 18h no sábado, 30 de maio. Não sei dizer a hora exata em que terminará; pode estar entre as 17 e as 19h. Garantirei que examinarei todas as entradas enviadas até as 14h e farei o possível para ver todas as entradas enviadas até as 16h; se as soluções forem enviadas depois disso, talvez eu não tenha chance de dar uma olhada justa antes de tomar minha decisão. Além disso, quanto mais cedo você enviar, mais chances terá de votar para poder me ajudar a escolher a melhor solução. Portanto, tente enviá-lo mais cedo do que no prazo.

Notas Unicode

Também houve alguma confusão sobre exatamente quais caracteres Unicode são permitidos. O intervalo de possíveis pontos de código Unicode é U+0000para U+10FFFF. Existem alguns pontos de código que nunca são válidos para uso como caracteres Unicode em qualquer intercâmbio aberto de dados; esses são os não caracteres e os pontos de código substitutos . Noncharacters são definidos no 5.1.0 secção Unidode Norma 16.7 como os valores U+FFFE, U+FFFF, U+nFFFE , U+nFFFF , onde n é 1- 10hexadecimal, e a gama U+FDD0-U+FDEF. Esses valores devem ser usados ​​para uso interno específico do aplicativo, e os aplicativos em conformidade podem retirar esses caracteres do texto processado por eles. Pontos de código substitutos, definidos na seção 3.8.0 do Unicode Standard 3.8 como U+D800- U+DFFF, são usados ​​para codificar caracteres além do Plano Multilíngue Básico em UTF-16; portanto, é impossível representar esses pontos de código diretamente na codificação UTF-16 e é inválido codificá-los em qualquer outra codificação. Assim, para os fins deste concurso, permitirei que qualquer programa que codifique imagens em uma sequência de no máximo 140 pontos de código Unicode do intervalo U+0000- U+10FFFFexcluindo todos os não caracteres e pares substitutos, conforme definido acima.

Vou preferir soluções que usam apenas caracteres atribuídos, e melhor ainda aqueles que usam subconjuntos inteligentes de caracteres atribuídos ou fazer algo interessante com o conjunto de caracteres que eles usam. Para obter uma lista dos caracteres atribuídos, consulte o banco de dados de caracteres Unicode ; observe que alguns caracteres são listados diretamente, enquanto outros são listados apenas como o início e o fim de um intervalo. Observe também que os pontos de código substitutos estão listados no banco de dados, mas são proibidos conforme mencionado acima. Se você quiser tirar proveito de certas propriedades dos caracteres para tornar o texto que você produz mais interessante, há uma variedade de bancos de dados com informações sobre caracteres , como uma lista de blocos de código nomeados e várias propriedades de caracteres.

Como o Twitter não especifica exatamente o conjunto de caracteres que eles suportam, serei indulgente com soluções que não funcionam com o Twitter porque certos caracteres contam caracteres extras ou extra. É preferível, mas não obrigatório, que todas as saídas codificadas possam ser transferidas ilesas via Twitter ou outro serviço de microblog, como o identi.ca . Eu vi alguma documentação declarando que o Twitter codifica a entidade <,> e &, e, portanto, conta esses caracteres como 4, 4 e 5, respectivamente, mas eu não testei isso sozinho, e o contador de caracteres JavaScript não parece contá-los dessa maneira.

Dicas e Links

  • A definição de caracteres Unicode válidos nas regras é um pouco complicada. A escolha de um único bloco de caracteres, como os Ideógrafos Unificados CJK (U + 4E00 – U + 9FCF), pode ser mais fácil.
  • Você pode usar bibliotecas de imagens existentes, como ImageMagick ou Python Imaging Library , para sua manipulação de imagens.
  • Se você precisar de ajuda para entender o conjunto de caracteres Unicode e suas várias codificações, consulte este guia rápido ou esta FAQ detalhada sobre UTF-8 no Linux e Unix .
  • Quanto mais cedo você encontrar sua solução, mais tempo eu (e outras pessoas votando) terei de analisá-la. Você pode editar sua solução se a melhorar; Baseará minha recompensa na versão mais recente quando der minha última olhada nas soluções.
  • Se você deseja que um formato de imagem fácil seja analisado e gravado (e não queira usar apenas um formato existente), sugiro usar o formato PPM . É um formato baseado em texto muito fácil de trabalhar, e você pode usar o ImageMagick para converter para e a partir dele.
Brian Campbell
fonte
Sinta-se livre para oferecer sugestões sobre as regras que escrevi nos comentários; Certamente, estou disposto a ajustá-los se as pessoas sentirem que precisam de esclarecimentos ou se estão muito especificadas demais.
27909 Brian Campbell
6
Você provavelmente deve dizer que o upload da imagem para um servidor e a postagem do URL não são válidas.
Shay Erlichmen
2
@ Shay Eu já não disse isso? "O processo de decodificação pode não ter acesso a nenhuma outra saída do processo de codificação além da especificada acima; ou seja, você não pode carregar a imagem em algum lugar e gerar a URL para o download do processo de decodificação, ou qualquer coisa boba como essa . "
27909 Brian Campbell
1
@ Konrad Rudolph, eu concordo; Eu não quis dizer "bobo" do ponto de vista prático (claramente, todo esse concurso é bobo do ponto de vista prático), eu quis dizer "bobo" no contexto deste concurso. O uso de um URI não é realmente um algoritmo de compressão, no sentido da teoria da informação, pois não permite transferir mais informações sem o simples uso de um canal alternativo. Você poderia fornecer ao codificador e decodificador um grande banco de dados de imagens e chamá-lo de compactação que funciona apenas em um conjunto limitado de imagens, mas especifiquei que você precisa lidar com uma imagem arbitrária.
277 Brian Campbell
2
Aqui estão alguns links que encontrei que podem ajudar as pessoas: azillionmonkeys.com/qed/unicode.html para obter uma explicação do intervalo válido de caracteres Unicode. Observe que as codificações UTF são as que podem codificar todo o intervalo Unicode; UCS-4 é um superconjunto de Unicode e UCS-2 e ASCII são subconjuntos. E em frente à compressão, aqui está uma técnica semelhante como o post original, embora ele está permitindo-se 1k em vez de 350 bytes: screamingduck.com/Article.php?ArticleID=46&Show=ABCE
Brian Campbell

Respostas:

244

Tudo bem, aqui está o meu: nanocrunch.cpp e o arquivo CMakeLists.txt para construí-lo usando o CMake. Ele se baseia na API Magick ++ ImageMagick para a maior parte de seu tratamento de imagens. Também requer que a biblioteca GMP seja aritmética de bignum para sua codificação de string.

Baseei minha solução na compressão de imagem fractal, com algumas reviravoltas únicas. A idéia básica é obter a imagem, redimensionar uma cópia para 50% e procurar peças em várias orientações semelhantes a blocos não sobrepostos na imagem original. É necessária uma abordagem de força muito bruta para essa pesquisa, mas isso facilita a introdução de minhas modificações.

A primeira modificação é que, em vez de apenas olhar para rotações e inversões de noventa graus, meu programa também considera orientações de 45 graus. É mais um bit por bloco, mas ajuda imensamente a qualidade da imagem.

A outra coisa é que armazenar um ajuste de contraste / brilho para cada componente de cor de cada bloco é muito caro. Em vez disso, armazeno uma cor fortemente quantizada (a paleta tem apenas 4 * 4 * 4 = 64 cores) que simplesmente se mistura em alguma proporção. Matematicamente, isso é equivalente a um brilho variável e a um ajuste constante de contraste para cada cor. Infelizmente, isso também significa que não há contraste negativo para mudar as cores.

Uma vez calculada a posição, orientação e cor de cada bloco, ele codifica isso em uma string UTF-8. Primeiro, ele gera um bignum muito grande para representar os dados na tabela de blocos e o tamanho da imagem. A abordagem para isso é semelhante à solução de Sam Hocevar - tipo de número grande, com um raio que varia de acordo com a posição.

Em seguida, ele converte isso em uma base, independentemente do tamanho do conjunto de caracteres disponível. Por padrão, ele faz uso total do conjunto de caracteres unicode atribuído, menos os caracteres menor que, maior que e comercial, controle, combinação e substituto e privado. Não é bonito, mas funciona. Você também pode comentar a tabela padrão e selecionar ASCII de 7 bits imprimível (excluindo novamente caracteres <,> e &) ou Ideógrafos unificados CJK. A tabela com os códigos de caracteres disponíveis é armazenada com um comprimento de execução codificado com execuções alternadas de caracteres inválidos e válidos.

De qualquer forma, aqui estão algumas imagens e horários (conforme medido no meu antigo P4 de 3,0 GHz) e compactados para 140 caracteres no conjunto unicode designado completo descrito acima. No geral, estou bastante satisfeito com o resultado. Se eu tivesse mais tempo para trabalhar nisso, provavelmente tentaria reduzir o bloqueio das imagens descomprimidas. Ainda assim, acho que os resultados são bons para a taxa de compressão extrema. As imagens descompactadas são um pouco impressionistas, mas acho relativamente fácil ver como os bits correspondem ao original.

Logotipo do estouro de pilha (8.6s para codificar, 7.9s para decodificar, 485 bytes):
http://i44.tinypic.com/2w7lok1.png

Lena (32,8s para codificar, 13,0s para decodificar, 477 bytes):
http://i42.tinypic.com/2rr49wg.png http://i40.tinypic.com/2rhxxyu.png

Mona Lisa (43,2 segundos para codificar, 14,5 segundos para decodificar, 490 bytes):
http://i41.tinypic.com/ekgwp3.png http://i43.tinypic.com/ngsxep.png

Editar: CJK caracteres unificados

Sam perguntou nos comentários sobre como usar isso com o CJK. Aqui está uma versão da Mona Lisa compactada para 139 caracteres do conjunto de caracteres CJK Unified:

http://i43.tinypic.com/2yxgdfk.png Clique para ampliar Clique para ampliar Clique para ampliar Clique para ampliar Clique para ampliar Clique para ampliar Clique para ampliar Clique para ampliar隤 慛 絖 銓 馿 掾 撄 粂 敽 稉 擎 蔍 螎 葙 峬 覧 絀 蹔 抆 惫 笻 笻 哜 搀 澐 芯 辍 辍 辍 垝 而 辍 猳 閺 而 猳 猳 猳 而 猳 猳 猳 猳 猳伆 杇 婣 唆 鐤 毤 埙 誖 萜 旖 鞰 萗 勹 鈱 哳 垬 濅 鬒 秀 瞛 认 认 気 狋 異 闥 珵 珵 珵 氙 餅 珵 熥 勳 餅 熥 熥 熥 餅 熥 熥 熥 熥 熥擸 萿

Os parâmetros de ajuste na parte superior do programa que usei para isso foram: 19, 19, 4, 4, 3, 10, 11, 1000, 1000. Também comentei a primeira definição de number_assigned e codes e descomentei o últimas definições para selecionar o conjunto de caracteres CJK Unified.

Boojum
fonte
Uau! Bom trabalho. Eu era cético em relação à compactação de imagem fractal para imagens tão pequenas, mas na verdade produz resultados bastante decentes. Também foi muito fácil de compilar e executar.
Brian Campbell #
1
Obrigado rapazes! Sam, você quer dizer resultados com apenas 140 caracteres CJK? Nesse caso, sim, será necessário ajustar os números na parte superior. O tamanho final em bits é de cerca de log2 (etapas_em_x etapas_em_y etapas_em_red etapas_em_verde etapas_em_blue) * blocks_in_x blocks_in_y + log2 (largura_máxima altura máxima).
Boojum 30/05/09
Edit: Há um * 16 no primeiro log2 () que eu deixei de fora. Isso é para as orientações possíveis.
Boojum 30/05/09
20
Alguém já twittou uma imagem usando isso ainda?
DBR
288

arquivos de imagem e fonte python (versões 1 e 2)

Versão 1 Aqui está minha primeira tentativa. Vou atualizar conforme for.

Eu tenho o logotipo SO até 300 caracteres quase sem perdas. Minha técnica usa a conversão para arte vetorial SVG, para que funcione melhor na arte de linha. Na verdade, é um compressor SVG, ainda exige que a arte original passe por um estágio de vetorização.

Na minha primeira tentativa, usei um serviço on - line para o rastreamento PNG, no entanto, existem MUITAS ferramentas gratuitas e não gratuitas que podem lidar com essa parte, incluindo potrace (código aberto).

Aqui estão os resultados

Logo SO original http://www.warriorhut.org/graphics/svg_to_unicode/so-logo.png Logo SO original decodificado http://www.warriorhut.org/graphics/svg_to_unicode/so-logo-decoded.png Após a codificação e decodificação

Personagens : 300

Tempo : não medido, mas praticamente instantâneo (sem incluir etapas de vetorização / rasterização)

O próximo estágio será incorporar 4 símbolos (pontos e comandos do caminho SVG) por caractere unicode. No momento, minha compilação python não possui suporte amplo a caracteres UCS4, o que limita minha resolução por caractere. Também limitei o intervalo máximo para a extremidade inferior do intervalo reservado unicode 0xD800; no entanto, depois de criar uma lista de caracteres permitidos e um filtro para evitá-los, teoricamente posso empurrar o número necessário de caracteres para 70-100 para o logo acima.

Uma limitação deste método no momento é que o tamanho da saída não é fixo. Depende do número de nós / pontos do vetor após a vetorização. A automação desse limite exigirá pixelização da imagem (que remove os principais benefícios dos vetores) ou execução repetida dos caminhos por um estágio de simplificação até que a contagem de nós desejada seja alcançada (o que atualmente estou fazendo manualmente no Inkscape).

Versão 2

ATUALIZAÇÃO : a v2 agora está qualificada para competir. Alterar:

  • Entrada / saída e depuração do controle da linha de comando
  • Usa o analisador XML (lxml) para manipular SVG em vez de regex
  • Empacota 2 segmentos de caminho por símbolo unicode
  • Documentação e limpeza
  • Estilo de suporte = "fill: color" e fill = "color"
  • Largura / altura do documento compactada em um único caractere
  • Cor do caminho compactada em um único caractere
  • A compactação de cores é obtida jogando fora 4 bits de dados por cor e agrupando-os em um caractere por conversão hexadecimal.

Personagens : 133

Tempo : alguns segundos

v2 decoded http://www.warriorhut.org/graphics/svg_to_unicode/so-logo-decoded-v2.png Após codificação e decodificação (versão 2)

Como você pode ver, existem alguns artefatos dessa vez. Não é uma limitação do método, mas um erro em algum lugar das minhas conversões. Os artefatos acontecem quando os pontos ultrapassam o intervalo de 0,0 a 127,0 e minhas tentativas de restringi-los tiveram um sucesso misto. A solução é simplesmente reduzir a imagem, no entanto, tive problemas para dimensionar os pontos reais em vez da prancheta ou da matriz do grupo e agora estou cansado demais para me importar. Em resumo, se seus pontos estão no intervalo suportado, geralmente funciona.

Acredito que a torção no meio se deve a uma alça que se move para o outro lado de uma alça à qual está ligada. Basicamente, os pontos estão muito próximos em primeiro lugar. A execução de um filtro simplificado sobre a imagem de origem antes da compactação deve corrigir isso e eliminar alguns caracteres desnecessários.

ATUALIZAÇÃO : Este método é adequado para objetos simples, então eu precisava de uma maneira de simplificar caminhos complexos e reduzir o ruído. Eu usei o Inkscape para esta tarefa. Tive alguma sorte em preparar caminhos desnecessários usando o Inkscape, mas não tive tempo para tentar automatizá-lo. Fiz alguns exemplos de svgs usando a função 'Simplificar' do Inkscape para reduzir o número de caminhos.

Simplificar funciona ok, mas pode ser lento com muitos caminhos.

exemplo de autotrace http://www.warriorhut.org/graphics/svg_to_unicode/autotrace_16_color_manual_reduction.png caixa cornell http://www.warriorhut.com/graphics/svg_to_unicode/cornell_box_simplified.png lena http://www.warriorhut.com/graphics /svg_to_unicode/lena_std_washed_autotrace.png

miniaturas rastreadas http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_autotrace.png

Aqui estão algumas fotos de ultra baixa resolução. Eles estariam mais próximos do limite de 140 caracteres, embora também seja necessária alguma compactação de caminho inteligente.

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

trianglulated http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_triangulated.png simplificado, manchas retiradas e triangulada.

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

ACIMA: Caminhos simplificados usando rastreamento automático .

Infelizmente, meu analisador não lida com a saída de rastreamento automático, então não sei como os pontos estão em uso ou até que ponto simplificar. Infelizmente, há pouco tempo para escrevê-lo antes do prazo. É muito mais fácil analisar do que a saída do inkscape.

SpliFF
fonte
2
Excelente! No começo, eu queria criar uma solução vetorial híbrida com bordas afiadas e áreas suaves, mas se mostrou muito complexa sem o uso de uma biblioteca de rastreamento (que eu não queria usar). Estou ansioso para ver até onde você pode chegar com seu método!
28611 sam hocevar
Agradável! Eu esperava ver algumas tentativas de abordagens quase sem perdas por vetorização. Isso significa que tem menor generalidade, mas maior qualidade para as imagens que abrange. É bom usar um serviço online para vetorização. Boa sorte em diminuir ainda mais o tamanho!
Brian Campbell
Eu consideraria a compactação de imagem e a codificação de caracteres como duas etapas diferentes - a técnica de Sam parece ser ideal para a codificação e pode ser facilmente incorporada a um programa independente. Você ganhará mais dinheiro concentrando-se na parte única da sua solução (ou seja, na parte de compressão) e apenas produzindo uma sequência de bits.
Ransom Mark
70
Uau. Essas imagens parecem realmente elegantes.
Rinat Abdullin
199

Minha solução completa pode ser encontrada em http://caca.zoy.org/wiki/img2twit . Possui os seguintes recursos:

  • Tempo de compressão razoável (cerca de 1 minuto para alta qualidade)
  • Descompressão rápida (uma fração de segundo)
  • Mantém o tamanho da imagem original (não apenas a proporção)
  • Qualidade de reconstrução decente (IMHO)
  • O comprimento da mensagem e o conjunto de caracteres (ASCII, CJK, Símbolos) podem ser escolhidos em tempo de execução
  • O comprimento da mensagem e o conjunto de caracteres são detectados automaticamente no momento da descompactação
  • Embalagem de informações muito eficiente

http://caca.zoy.org/raw-attachment/wiki/img2twit/so-logo.png http://caca.zoy.org/raw-attachment/wiki/img2twit/twitter4.png

蜥 秓 鋖 筷 聝 庯 祩 皙 靊 獜 岨 幻 寤 厎 趆 脘 搇 梄 踥 桻 戂 戂 溥 欇 渹 裏 骿 骿 骿 髙 蚙 骿 弫 潮 蚙 弫 弫 弫 蚙 弫 弫 弫 弫 弫玧 霫 鏓 蓕 戲 袮 足 庭 侅 凼 飙 驅 據 嘛 掔 倾 诗 籂 阉 嶹 椿 椿 糢 墤 渽 緛 更 更 更 棫 颗 更 珸 齸 颗 珸 珸 珸 颗 珸 珸 珸 珸 珸擲 舥 攩 寉 鈶 庭 璱 耓 庁 努 樀 肝 亖 弜 喆 蝞 躐 葌 熲 谎 蛪 曟 暙 刍 镶 慸 曟 刍 镶 慸 曟 暙 镶 葌 曟 暙 蝞 躐

Aqui está uma visão geral do processo de codificação:

  • O número de bits disponíveis é calculado a partir do comprimento desejado da mensagem e do conjunto de caracteres utilizável
  • A imagem de origem é segmentada em tantas células quadradas quanto os bits disponíveis permitem
  • Um número fixo de pontos (atualmente 2) é afetado para cada célula, com coordenadas iniciais e valores de cores
  • O seguinte é repetido até que uma condição de qualidade seja atendida:
    • Um ponto é escolhido aleatoriamente
    • Uma operação é executada aleatoriamente neste ponto (movendo-a para dentro de sua célula, alterando sua cor)
    • Se a imagem resultante (veja o processo de decodificação abaixo) estiver mais próxima da imagem de origem, a operação será mantida
  • O tamanho da imagem e a lista de pontos são codificados em UTF-8

E este é o processo de decodificação:

  • O tamanho e os pontos da imagem são lidos no fluxo UTF-8
  • Para cada pixel na imagem de destino:
    • A lista de neigbours naturais é calculada
    • A cor final do pixel é definida como uma média ponderada das cores de seus vizinhos naturais

O que acredito ser a parte mais original do programa é o fluxo de bits. Em vez de empacotar valores alinhados por bits ( stream <<= shift; stream |= value), compacto valores arbitrários que não estão na faixa de dois potências ( stream *= range; stream += value). Isso requer cálculos bignum e, é claro, é muito mais lento, mas me dá 2009,18 bits em vez de 1960 ao usar os caracteres CJK principais do 20902 (são mais três pontos que posso colocar nos dados). E ao usar ASCII, ele me fornece 917,64 bits em vez de 840.

Decidi contra um método para o cálculo inicial da imagem que exigiria armas pesadas (detecção de canto, extração de recursos, quantização de cores ...) porque não tinha certeza no início que realmente ajudaria. Agora percebo que a convergência é lenta (1 minuto é aceitável, mas é lento, no entanto) e posso tentar melhorar isso.

O loop de ajuste principal é pouco inspirado no algoritmo de pontilhamento Direct Binary Seach (em que os pixels são trocados ou invertidos aleatoriamente até obter um meio-tom melhor). O cálculo da energia é uma distância quadrática média quadrática simples, mas realizo primeiro um filtro mediano de 5x5 na imagem original. Um borrão gaussiano provavelmente representaria melhor o comportamento do olho humano, mas eu não queria perder arestas vivas. Também decidi contra o recozimento simulado ou outros métodos difíceis de ajustar, porque não tenho meses para calibrar o processo. Portanto, o sinalizador "qualidade" representa apenas o número de iterações que são executadas em cada ponto antes do final do codificador.

http://caca.zoy.org/raw-attachment/wiki/img2twit/Mona_Lisa_scaled.jpg http://caca.zoy.org/raw-attachment/wiki/img2twit/twitter2.png

苉 憗 揣 嶕 繠 霮 墧 蒆 棌 蓳 縳 樟 赒 肴 飗 噹 砃 燋 任 朓 釰 釰 靂 陴 貜 犟 喗 喗 喗 荛 嫤 喗 氲 簵 嫤 氲 氲 氲 嫤 氲 氲 氲 氲 氲激 躙 憮 鄴 甮 駪 惾 嫥 綖 矯 坼 堭 颽 箽 赭 飉 訥 偁 箝 窂 熛 熛 漧 衆 橼 愀 玴 玴 玴 裋 抲 玴 鶼 呍 抲 鶼 鶼 鶼 抲 鶼 鶼 鶼 鶼 鶼苾 绒 酯 嵞 脔 污 囉 棺 则 曚 鸸 職 銛 蒝 礭 鱚 蟺 稿 纡 醾 陴 鳣 尥 蟀 惘 祤 尥 蟀 惘 祤 鳣 尥 惘 稿 鳣 尥 鱚 蟺

Embora nem todas as imagens sejam compactadas bem, estou surpreso com os resultados e realmente me pergunto quais outros métodos existem que podem compactar uma imagem para 250 bytes.

Eu também tenho pequenos filmes da evolução do estado do codificador a partir de um estado inicial aleatório e de um estado inicial "bom" .

Editar : aqui está como o método de compactação se compara ao JPEG. À esquerda, o jamoes está acima da imagem de 536 bytes. À direita, a Mona Lisa compactou até 534 bytes usando o método descrito aqui (os bytes mencionados aqui se referem a bytes de dados, portanto, ignorando os bits desperdiçados usando caracteres Unicode):

http://caca.zoy.org/raw-attachment/wiki/img2twit/minimona.jpg http://caca.zoy.org/raw-attachment/wiki/img2twit/minimona2.png

Editar : acabou de substituir o texto CJK pelas versões mais recentes das imagens.

sam hocevar
fonte
Na verdade, não preciso ser capaz de executar o código (coloquei a parte de executá-lo nas diretrizes, como sugestão, não nas regras); Eu preferiria poder executá-lo, mas analisarei mais a qualidade das imagens geradas, o código e quaisquer truques ou algoritmos interessantes. Se eu quiser executá-lo e exigir pacotes que não tenho ou não quero instalar no meu sistema principal, basta inicializar uma instância do Amazon EC2 e instalá-la. Desde que você esteja trabalhando com bibliotecas empacotadas para uma das principais distribuições, eu devo executá-la. Sinta-se livre para usar CGAL.
27909 Brian Campbell
2
Ok, aqui está a minha solução (código fonte): caca.zoy.org/browser/libpipi/trunk/examples/img2twit.cpp Minha tentativa de explicação e alguns exemplos estão em caca.zoy.org/wiki/img2twit
sam hocevar
2
Eu realmente gosto da sua solução. Você deve tentar reduzir o número de valores atribuídos ao canal azul, pois o olho humano não consegue resolver muito bem o azul: nfggames.com/games/ntsc/visual.shtm ; isso permitirá que você tenha mais detalhes às custas de algumas informações sobre cores serem perdidas. Ou talvez atribuí-lo a verde?
Rpetrich 26/05/09
5
Bom ponto. Tentei algumas variações dessa idéia (veja os comentários antes da definição de RANGE_X), mas não muito detalhadamente. Como você pode ver, o uso de 5 valores de azul em vez de 6 aumentou o erro um pouco menos do que o uso de 7 valores de verde. Não tentei fazer as duas coisas por preguiça. Outro problema que tenho é que não tenho uma função de erro muito boa. Atualmente, uso ∑ (∆r² + ∆g² + ∆b²) / 3, que funciona bem. Tentei ∑ (0,299∆r² + 0,587∆g² + 0,114∆b²), com base (sem justificativa física) no componente Y da YUV, mas era muito tolerante com erros azuis. Vou tentar encontrar trabalhos sobre esse assunto.
23610 sam samococar
2
@ rpetrich: Modifiquei o programa para aumentar dinamicamente os intervalos de r / g / b, desde que haja bits suficientes disponíveis. Isso garante que nunca desperdiçamos mais de 13 bits em todo o fluxo de bits (mas, na prática, geralmente é 1 ou 2). E as imagens parecem um pouco melhores.
27610 sam samococar
45

O seguinte não é um envio formal, pois meu software não foi adaptado de forma alguma para a tarefa indicada. O DLI pode ser descrito como um codec de imagem com perda de propósito geral otimizado. É o detentor do registro PSNR e MS-SSIM para compactação de imagem, e pensei que seria interessante ver o desempenho dessa tarefa em particular. Usei a imagem de referência da Mona Lisa fornecida e a reduzi para 100x150, depois usei o DLI para compactá-la para 344 bytes.

Mona Lisa DLI http://i40.tinypic.com/2md5q4m.png

Para comparação com as amostras compactadas JPEG e IMG2TWIT, usei o DLI para compactar a imagem em 534 bytes também. O JPEG tem 536 bytes e IMG2TWIT é 534 bytes. As imagens foram dimensionadas para aproximadamente o mesmo tamanho para facilitar a comparação. JPEG é a imagem da esquerda, IMG2TWIT é o centro e DLI é a imagem da direita.

Comparação http://i42.tinypic.com/302yjdg.png

A imagem DLI consegue preservar algumas das características faciais, principalmente o famoso sorriso :).

Brian Campbell
fonte
6
Opa O texto acima deve ser creditado a Dennis Lee, que o enviou originalmente. Acabei de editá-lo para incorporar as imagens em linha e vincular à referência que encontrei no Google. E devo dizer, uau, estou impressionado com a compressão. Vou ter que verificar a compressão DLI.
27909 Brian Campbell
1
A propósito, o autor do DLI menciona um "longo tempo de processamento". Como não consigo executar o software dele, você poderia nos fornecer números aproximados de tempo de compactação?
31513 sam hocevar
1
Usando um AMD Athlon64 2.4Ghz, a compactação da imagem 100x150 da Mona Lisa leva 38seg e a descompactação 6seg. A compressão para um máximo de 251 bytes é mais difícil, a qualidade da saída é significativamente reduzida. Usando a imagem de referência da Mona Lisa, eu a reduzi para 60x91 e usei o DLI para compactá-la para 243 bytes (o mais próximo de 251 sem passar por cima). Essa é a saída i43.tinypic.com/2196m4g.png Os detalhes não estão próximos do DLI de 534 bytes, mesmo que a taxa de bits tenha sido reduzida em apenas 50%. A estrutura da imagem foi mantida razoavelmente bem.
1
Decidiu facilitar a comparação das amostras compactadas de 250 bytes. O DLI de 243 bytes foi ampliado e colocado ao lado da amostra IMG2TWIT. IMG2TWIT à esquerda, DLI à direita. Aqui está a imagem i40.tinypic.com/30ndks6.png
1
O DLI usa um parâmetro de qualidade como JPEG, portanto, tentativa e erro são necessários se um tamanho de saída desejado for desejado.
21

A visão geral da minha solução seria:

  1. Começo com o cálculo da quantidade máxima de dados brutos que você pode ajustar em 140 caracteres utf8.
    • (Suponho utf8, que é o que o site original alegou que o twitter armazenou suas mensagens. Isso difere da declaração do problema acima, que pede utf16.
    • Usando esse faq do utf8 , calculo que o número máximo de bits que você pode codificar em um único caractere utf8 é 31 bits. Para fazer isso, eu usaria todos os caracteres que estão no intervalo U-04000000 - U-7FFFFFFF. (1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx, existem 31 x, portanto, eu poderia codificar até 31 bits).
    • 31 bits vezes 140 caracteres é igual a 4340 bits. Divida isso por 8 para obter 524,5 e arredonde para 542 bytes .
    • (Se nos restringirmos a utf16, poderíamos armazenar apenas 2 bytes por caractere, o que equivaleria a 280 bytes).
  2. Comprima a imagem usando a compactação jpg padrão.
    • Redimensione a imagem para aproximadamente 50x50px e tente compactá-la em vários níveis de compactação até obter uma imagem o mais próxima possível de 542 bytes possível sem passar por cima.
    • Este é um exemplo da mona lisa compactada em 536 bytes.
  3. Codifique os bits brutos da imagem compactada em caracteres utf-8.
    • Substitua cada x nos seguintes bytes: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx pelos bits da imagem.
    • Essa parte provavelmente seria a parte em que a maioria do código precisaria ser escrita, porque não existe nada que exista atualmente que faça isso.

Sei que você estava pedindo código, mas não quero gastar muito tempo para codificá-lo. Imaginei que um design eficiente pudesse pelo menos inspirar alguém a codificar isso.

Eu acho que o principal benefício da minha solução proposta é que ela está reutilizando o máximo de tecnologia existente possível. Pode ser divertido tentar escrever um bom algoritmo de compactação, mas é garantido que existe um algoritmo melhor por aí, provavelmente escrito por pessoas com um diploma em matemática mais alta.

Uma outra observação importante é que, se for decidido que utf16 é a codificação preferida, essa solução se desfaz. JPEGs realmente não funcionam quando compactados até 280 bytes. Embora, talvez exista um algoritmo de compactação melhor que o jpg para esta declaração de problema específica.

Stephen McCarthy
fonte
Estou no trabalho agora, mas definitivamente implemento essa solução quando cheguei em casa.
Paulo Santos
2
Pela minha experiência, parece que UTF-16 é realmente como o Twitter conta caracteres; Os caracteres BMP contam como 1 e os caracteres de plano superior contam como 2. Não está documentado, mas é assim que o contador de caracteres JavaScript conta quando você digita na caixa de entrada. Também é mencionado nos comentários no tópico original. Não tentei enviar por meio da API para verificar se o contador está quebrado; se for, atualizarei o problema para as restrições reais. No entanto, é provável que você não possa usar UTF-8 arbitrário, pois muitas dessas sequências mais longas que você pode codificar não são Unicode válidas.
27909 Brian Campbell
4
Após testar com a API, eles contam por caracteres Unicode (pontos de código), não por unidades de código UTF-16 (é o contador de caracteres JavaScript que conta via UTF-16, pois aparentemente é isso que o método de tamanho JavaScript faz) . Para que você possa obter um pouco mais de informação; caracteres Unicode válidos estão no intervalo U + 0000 a U + 10FFFF (um pouco mais de 20 bits por caractere; 2 ^ 20 + 2 ^ 16 valores possíveis por caractere). UTF-8 permite codificação de mais valores que são permitidos em Unicode, por isso, se você restringir-se a Unicode, você pode obter cerca de 350 bytes de espaço, não 542.
Brian Campbell
3
Essa mona lisa de 536 bytes parece surpreendentemente boa, dada a extrema compressão!
214/09 Chris
3
Atualmente, podemos codificar 129.775 caracteres Unicode diferentes (atribuídos, sem controle e não privados). Se nos restringirmos a esse subconjunto, será um total de 2377 bits ou 297 bytes. Código aqui: porg.es/blog/what-can-we-fit-in-140-characters
porges
20

Ok, estou atrasado para o jogo, mas mesmo assim fiz o meu projeto.

É um algoritmo genético de brinquedo que usa círculos coloridos translúcidos para recriar a imagem inicial.

Recursos:

  • Lua pura. É executado em qualquer lugar onde um intérprete Lua é executado.
  • usa o formato netpbm P3
  • vem com um conjunto abrangente de testes de unidade
  • preserva o tamanho da imagem original

Mis-feautres:

  • lento
  • nessas restrições de espaço, preserva apenas o esquema de cores básico da imagem inicial e um esboço geral de algumas características da mesma.

Aqui está um exemplo de twit que representa Lena: 犭 楊 谷 杌 螦 扝 俄 归 晃 客 猘 摈 硰 划 刀 萕 码 摃 斢 斢 蜁 划 摃 斢 嘁 蜁 簜 摃 斢 蜁 澹 簜 斢 嘁 蜁 簜 僨 斢 團 澹岂 掂 戇 耔 攋 昸 箆 亲 嬎 栃 兡 塅 受 橯 恰 应 戞 优 猫 僘 吱 吱 賾 卣 朸 杈 綍 綍 綍 猕 厥 綍 尕 熚 厥 尕 尕 尕 厥 尕 尕 尕 尕 尕虲 兙 罨 縨 炘 弅 慌 螎 熰 宑 簫 柢 橙 拃 丨 蜊 缩 昔 儻 舭 癳 癳 冂 囤 璟 彔 兠 兠 兠 侑 訜 兠 嫡 琠 訜 嫡 嫡 嫡 訜 嫡 嫡 嫡 嫡 嫡厇 廩 焛 瀻 严 刱 垫 仔

lena original Lena codificada

O código está em um repositório Mercurial em bitbucket.org. Confira http://bitbucket.org/tkadlubo/circles.lua

Tadeusz A. Kadłubowski
fonte
2
Impressionante! Cria imagens elegantes e artísticas. Fico feliz que as pessoas ainda estejam trabalhando nisso; Foi muito divertido ver todas as diferentes abordagens.
Brian Campbell
1
Gostaria de ver isso usado como uma sobreposição transparente no original, dando algo como o efeito bokeh.
22811 Nick Radford
19

A seguir, é minha abordagem do problema e devo admitir que este foi um projeto bastante interessante de se trabalhar, está definitivamente fora do meu domínio normal de trabalho e me deu algo novo para aprender.

A idéia básica por trás da minha é a seguinte:

  1. Amostra para baixo da escala de cinza da imagem, de modo que houvesse um total de 16 tons diferentes
  2. Pré-forma RLE na imagem
  3. Empacote os resultados nos caracteres UTF-16
  4. Pré-forma RLE nos resultados compactados para remover qualquer duplicação de caracteres

Acontece que isso funciona, mas apenas em uma extensão limitada, como você pode ver nas imagens de exemplo abaixo. Em termos de saída, o que se segue é um exemplo de tweet, especificamente para a imagem Lena mostrada nas amostras.

儂 乤 万 乐 唂 倂 倁 企 儂 2 倁 倁 企 倁 企 企 伂 企 企 企 企 企 伂 倁 倁 倁 倁 倁 倁 倁 倁 倁 倁 倁 倁 倁 倁 倁 倁 企 企 倁 企 企 企 企 企 企 企 企 倁 企 企伂 2 伂 伂 5 企 倁 企 伂 皗 鞹 鐾 륶 䦽 阹 럆 䧜 籫 릹 靭 욶 옷뎷 歩 㰷 歉 䴗 鑹 㞳 㞳 㬼 獴 돗 돗 鍴 㭾 鞷 㬼 獴 鍴 祳 㞳 㬼 돗 鍴 祳 㞳 獴 鍴 祳 㞳 㬼 獴 鍴 祳 㞳 㬼 돗 鍴 祳 㞳 㬼 돗 鍴

Como você pode ver, tentei restringir um pouco o conjunto de caracteres; no entanto, tive problemas ao armazenar os dados de cores da imagem. Além disso, esse esquema de codificação também tende a desperdiçar vários bits de dados que podem ser usados ​​para obter informações adicionais sobre a imagem.

Em termos de tempo de execução, para imagens pequenas, o código é extremamente rápido, cerca de 55ms para as imagens de amostra fornecidas, mas o tempo aumenta com imagens maiores. Para a imagem de referência Lena de 512x512, o tempo de execução foi de 1182ms. Devo observar que as probabilidades são muito boas de que o código em si não seja muito otimizado para o desempenho (por exemplo, tudo é trabalhado como um bitmap ) para que os tempos possam diminuir um pouco após alguma refatoração.

Sinta-se à vontade para me oferecer sugestões sobre o que eu poderia ter feito melhor ou o que pode estar errado com o código. A lista completa dos tempos de execução e da amostra de saída pode ser encontrada no seguinte local: http://code-zen.info/twitterimage/

Update One

Atualizei o código RLE usado ao compactar a string do tweet para fazer uma retrospectiva básica e, se sim, use isso para a saída. Isso funciona apenas para os pares de valores numéricos, mas salva alguns caracteres de dados. O tempo de execução é mais ou menos o mesmo, assim como a qualidade da imagem, mas os tweets tendem a ser um pouco menores. Vou atualizar o gráfico no site à medida que concluir o teste. O que se segue é uma das seqüências de exemplo de tweet, novamente para a versão pequena do Lena:

乤 乤 万 乐 唂 倂 倁 企 儂 2 倁 3 企 倁 ウ 伂 8 伂 伂 エ 伂 5 企 倂 倃 伂 グ グ 儁 企 2 伂 倃 ガ 倁 ジ 倃 4 企 倂 企 倁 企 伂 倁 倁企 伂 쥹 皗 鞹 륶 䦽 籫 릹 욶 옷뎷 歩 歉 歉 䴗 鑹 㞳 鞷 㬼 獴 鏙 돗 鍴 鍴 㭾 돗 鍴 㭾 鍴 㭾 鍴 㭾 鍴 祳 㭾

Atualização dois

Outra pequena atualização, mas modifiquei o código para agrupar os tons de cores em grupos de três, em vez de quatro, isso usa mais espaço, mas, a menos que eu esteja perdendo alguma coisa, isso significa que caracteres "estranhos" não aparecem mais onde a cor dados são. Além disso, atualizei a compactação um pouco mais para que agora ela possa atuar sobre toda a cadeia, em vez de apenas o bloco de contagem de cores. Ainda estou testando os tempos de execução, mas eles parecem ter melhorado nominalmente; no entanto, a qualidade da imagem ainda é a mesma. O que se segue é a versão mais recente do tweet de Lena:

2 儂 万 乐 唂 倂 倁 企 儂 2 倁 倁 企 伂 8 伂 伂 エ 伂 5 伂 倂 倃 伂 グ 儁 儁 企 企 2 伂 倃 ガ 倁 ジ 企 4 倃 倂 企 倁 企 伂 倁 倁企 伂 坹 坼 坶 吹 婩 媷 劝 咶 坼 妛 啭 奩 嗆 婣 冷 咛 啫 凃 佶 佶 坍 均 喳 女 决 决 决 决 决 决 唓 唓 唓 唓 唓 唓 奎 唓 唓 唓 奎 唓商 嗉 乃

Logotipo StackOverflow http://code-zen.info/twitterimage/images/stackoverflow-logo.bmp Cornell Box http://code-zen.info/twitterimage/images/cornell-box.bmp Lena http: // code-zen .info / twitterimage / images / lena.bmp Mona Lisa http://code-zen.info/twitterimage/images/mona-lisa.bmp

Rob Z
fonte
1
Ótimo, obrigado pela entrada! A escala de cinza realmente funciona muito bem para a maioria deles, embora Lena seja um pouco difícil de entender. Eu estava procurando sua fonte, mas recebi um 404; você poderia ter certeza de que está lá em cima?
Brian Campbell
Verifique agora, eu estava atualizando o site para que você possa ter me pego entre as atualizações.
Rjzii 30/05/09
Sim, eu posso fazer o download agora. Agora, é claro, preciso descobrir se consigo o Mono compilá-lo.
Brian Campbell #
Sim! Funciona em Mono, eu compilado com "gmcs -r System.Drawing TwitterImage.cs Program.cs" e correr com "mono TwitterImage.exe codificar lena.png lena.txt"
Brian Campbell
Legal! Fiz uma verificação dupla para garantir que as bibliotecas que eu estava usando estavam listadas para o Mono, mas ainda não trabalhei com o Mono, por isso não tinha certeza se o faria ou não.
Rjzii 30/05/09
15

Esse algoritmo genético que Roger Alsing escreveu possui uma boa taxa de compressão, à custa de longos tempos de compressão. O vetor resultante de vértices pode ser ainda mais compactado usando um algoritmo com ou sem perdas.

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

Seria um programa interessante para implementar, mas vou sentir falta.

CiscoIPPhone
fonte
12

No desafio original, o limite de tamanho é definido como o que o Twitter ainda permite enviar se você colar o texto na caixa de texto e pressionar "atualizar". Como algumas pessoas perceberam corretamente, isso é diferente do que você pode enviar como uma mensagem de texto SMS do seu celular.

O que não é mencionado explicitamente (mas qual era minha regra pessoal) é que você deve poder selecionar a mensagem tweetada no seu navegador, copiá-la na área de transferência e colá-la em um campo de entrada de texto do seu decodificador para que ele possa ser exibido. É claro que você também pode salvar a mensagem como um arquivo de texto e lê-la novamente ou escrever uma ferramenta que acessa a API do Twitter e filtra qualquer mensagem que se pareça com um código de imagem (marcadores especiais alguém? Wink wink ). Mas a regra é que a mensagem deve ter passado pelo Twitter antes que você possa decodificá-la.

Boa sorte com os 350 bytes - duvido que você possa usá-los.

Quasimondo
fonte
1
Sim, adicionei uma rubrica de pontuação que indica que restrições mais restritas ao conjunto de caracteres são preferidas, mas não necessárias. Gostaria de ter uma regra que exija que as mensagens passem ilesos pelo Twitter, mas que seriam necessárias muitas tentativas e erros para descobrir os detalhes precisos do que funciona, e eu queria deixar uma margem de manobra para permitir usos criativos do espaço de código. Portanto, o único requisito no meu desafio são 140 caracteres Unicode válidos. A propósito, obrigado pela visita! Eu realmente gosto da sua solução e quero ver se algum dos kibitzers pode realmente melhorar isso.
27909 Brian Campbell
12

A publicação de uma imagem monocromática ou em escala de cinza deve melhorar o tamanho da imagem que pode ser codificada nesse espaço, pois você não se importa com cores.

Possivelmente aumentando o desafio de fazer o upload de três imagens que, quando recombinadas, fornecem uma imagem em cores, mantendo uma versão monocromática em cada imagem separada.

Adicione um pouco de compressão ao acima e ele pode começar a parecer viável ...

Agradável!!! Agora vocês despertaram meu interesse. Nenhum trabalho será feito pelo resto do dia ...

Gineer
fonte
9
s / peaked / piqued / g
eleven81
1
Gosto da ideia de três imagens, deve ser possível implementar essa ideia no twitter e o resultado seria muito bom.
2927 Makis
9

Em relação à parte de codificação / decodificação deste desafio. base16b.org é minha tentativa de especificar um método padrão para codificar com segurança e eficiência dados binários nos planos Unicode superiores.

Algumas funcionalidades :

  • Usa apenas as áreas de usuário privadas do Unicode
  • Codifica até 17 bits por caractere; quase três vezes mais eficiente que o Base64
  • Uma implementação Javascript de referência de codificação / decodificação é fornecida
  • Algumas codificações de amostra estão incluídas, incluindo Twitter e Wordpress

Desculpe, esta resposta chega muito tarde para a competição original. Comecei o projeto independentemente deste post, que descobri no meio do caminho.


fonte
8

A idéia de armazenar várias imagens de referência é interessante. Seria tão errado armazenar, digamos, 25Mb de imagens de amostra, e pedir ao codificador para compor uma imagem usando bits dessas? Com uma tubulação tão minúscula, a maquinaria de cada extremidade é necessariamente maior do que o volume de dados que passa, então qual é a diferença entre 25Mb de código e 1Mb de código e 24Mb de dados de imagem?

(observe que as diretrizes originais descartaram restringir a entrada a imagens já existentes na biblioteca - não estou sugerindo isso).


fonte
1
Isso seria bom, desde que você tenha uma quantidade fixa e finita de dados em qualquer um dos pontos de extremidade. Obviamente, você precisaria demonstrar que ele funciona com imagens que não estão no conjunto de treinamento, como qualquer problema estatístico de processo de linguagem natural. Eu adoraria ver algo que adota uma abordagem estatística para a codificação de imagens.
27909 Brian Campbell
16
Eu, por exemplo, adoraria ver Mona Lisa refeito usando apenas a arte dos fãs de Boba Fett como fonte.
Nosredna
Eu concordo - a abordagem fotomosaica parece estar dentro das regras e seria extremamente interessante ver alguém dar uma facada.
274/09 An̲̳̳drew
8

Idéia estúpida, mas sha1(my_image)resultaria em uma representação "perfeita" de qualquer imagem (ignorando colisões). O problema óbvio é que o processo de decodificação requer quantidades excessivas de força bruta.

Monocromático de 1 bit seria um pouco mais fácil. Cada pixel se torna 1 ou 0, para que você tenha 1000 bits de dados para uma imagem de 100 * 100 pixels. Como o hash SHA1 possui 41 caracteres, podemos encaixar três em uma mensagem, apenas para força bruta 2 conjuntos de 3333 bits e um conjunto de 3334 (embora mesmo isso provavelmente ainda seja desordenado)

Não é exatamente prático. Mesmo com a imagem 100 * 100px de 1 bit de comprimento fixo, existe .., supondo que eu não esteja calculando mal as combinações 49995000 ou 16661667 quando dividido em três.

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
dbr
fonte
10
O problema com sha1 (minha_image) é que, se você gastasse seu tempo brutalmente forçando-o, provavelmente encontraria muitas colisões antes de encontrar a imagem real; e, é claro, forçar brutalmente sha1 é praticamente inviável em termos computacionais.
Brian Campbell
5
Ainda melhor que a compressão SHA1: meu algoritmo de compressão "flickr"! Etapa 1: faça o upload da imagem no flickr. Etapa 2: publique um link para ele no twitter. Tadda! Apenas 15 bytes usam!
NiXar 19/06/2009
2
niXar: Não, regra 3.4: "O processo de decodificação pode não ter acesso a nenhuma outra saída do processo de codificação além da especificada acima; ou seja, você não pode carregar a imagem em algum lugar e gerar a URL para o processo de decodificação. download, ou qualquer coisa boba assim. "
DBR
6
Eu sei, eu estava sendo sarcástico.
NiXar 26/06/2009
0

Idéia: você poderia usar uma fonte como paleta? Tente quebrar uma imagem em uma série de vetores, tentando descrevê-los com uma combinação de conjuntos de vetores (cada caractere é essencialmente um conjunto de vetores). Isso está usando a fonte como um dicionário. Eu poderia, por exemplo, usar al para uma linha vertical e um - para uma linha horizontal? Apenas uma ideia.

Maurits
fonte