Crie um programa que possa reorganizar os pixels da imagem para que não seja reconhecido. No entanto, seu programa poderá convertê-lo novamente para a imagem original.
Você pode escrever duas funções - para codificação e decodificação, no entanto, uma função aplicada repetidamente fornece a imagem original (exemplo em matemática - f(x) = 1 - x
) é um bônus.
Também produzir algum padrão na saída também oferece bônus.
A imagem pode ser representada como matriz 1D / 2D ou objeto de imagem, se o seu idioma suportar. Observe que você só pode alterar a ordem dos pixels!
Será lógico selecionar o código vencedor, que produz uma imagem menos reconhecível, no entanto, não sei como mensurá-lo exatamente, todas as maneiras que posso imaginar podem ser enganadas. Por isso, escolhi essa pergunta para ser um concurso de popularidade - deixe os usuários escolherem a melhor resposta!
Imagem de teste 1 (800 x 422 px): Imagem de teste 2 (800 x 480 px): forneça uma imagem de saída de código.
fonte
Respostas:
Python 2.7 (com PIL) - sem pseudo-aleatoriedade
Eu divido a imagem em 2 por 2 blocos (ignorando o restante) e giro cada bloco em 180 graus, depois faço o mesmo com 3 por 3 blocos, depois 4, etc. até algum parâmetro BLKSZ. Então eu faço o mesmo para BLKSZ-1, depois BLKSZ-2, todo o caminho de volta para 3 e depois para 2. Esse método se inverte exatamente; a função desembaralhar é a função embaralhar.
O código :
Dependendo do tamanho do bloco, é possível fazer com que o cálculo elimine todas as semelhanças com a imagem original: (BLKSZ = 50)
Ou torne a computação eficiente: (BLKSZ = 10)
fonte
BLKSZ = 10
paisagem é muito legal!C #, WinForm
Editar Alterando a maneira como você preenche a matriz de coordenadas, você pode ter padrões diferentes - veja abaixo
Você gosta desse tipo de padrão?
Bônus:
Troca aleatória exatamente uma vez todos os pixels na metade superior com todos os pixels na metade inferior. Repita o mesmo procedimento para desembaralhar (bônus).
Código
Scramble.cs
Scramble.designer.cs
Program.cs
Marque 'Código não seguro' na propriedade do projeto para compilar.
Padrão complexo
Altere a primeira parte da função de trabalho, até Application.DoEvents:
fonte
C, desfoque arbitrário, facilmente reversível
Tarde para a festa. Aqui está a minha entrada!
Este método faz um borrão embaralhado. Eu chamo de scramblur . É extremamente simples. Em um loop, ele escolhe um pixel aleatório e o troca com um pixel próximo escolhido aleatoriamente em um modelo de tela toroidal. Você especifica a distância máxima que define o que "pixel próximo" significa (1 significa sempre escolher um pixel adjacente), o número de iterações e, opcionalmente, uma semente de número aleatório. Quanto maior a distância máxima e maior o número de iterações, mais desfocado o resultado.
É reversível especificando um número negativo de iterações (isso é simplesmente uma conveniência da interface da linha de comandos; na verdade, não existe iterações negativas). Internamente, ele usa um LCPRNG personalizado de 64 bits (gerador de números pseudo-aleatórios lineares congruentes) e pré-gera um bloco de valores. A tabela permite fazer um loop pelo bloco para frente ou para trás para embaralhar ou desembaralhar, respectivamente.
Demo
Nas duas primeiras imagens, à medida que você rola para baixo, cada imagem é desfocada usando um deslocamento máximo mais alto: Mais acima é a imagem original (por exemplo, deslocamento de 0 pixel), seguida por 1, 2, 4, 8, 16, 32, 64 , 128 e finalmente 256. A contagem da iteração é 10⁶ = 1.000.000 para todas as imagens abaixo.
Nas duas segundas imagens, cada imagem é desfocada usando um deslocamento progressivamente mais baixo - por exemplo, mais embaçado para menos embaçado - de um deslocamento máximo de 256 para 0. Desfrute!
E para as próximas duas imagens, você pode ver as progressões em tamanho real aqui e aqui :
Código
Eu hackeei isso juntos em cerca de uma hora enquanto acordava hoje de manhã e ele quase não contém documentação. Posso voltar em alguns dias e adicionar mais documentação posteriormente, se as pessoas solicitarem.
fonte
Python 3.4
Quando o bônus 2 é alcançado, usando uma imagem-chave adicional, o bônus 1 não é perdido. O programa ainda é auto-inverso, desde que seja executado com a mesma imagem-chave novamente.
Uso padrão
Imagem de teste 1:
Imagem de teste 2:
A execução do programa com um único arquivo de imagem como argumento salva um arquivo de imagem com os pixels misturados uniformemente por toda a imagem. A execução novamente com a saída codificada salva um arquivo de imagem com a codificação aplicada novamente, o que restaura o original, pois o processo de codificação é inverso.
O processo de codificação é inverso, porque a lista de todos os pixels é dividida em 2 ciclos, para que cada pixel seja trocado por um e apenas um outro pixel. A execução uma segunda vez troca todos os pixels com os pixels com os quais foi trocada pela primeira vez, colocando tudo de volta ao início. Se houver um número ímpar de pixels, haverá um que não se moverá.
Graças à resposta de mfvonh como a primeira a sugerir 2 ciclos.
Uso com uma imagem principal
Imagem de teste de embaralhamento 1 com imagem de teste 2 como imagem principal
Imagem de teste de codificação 2 com imagem de teste 1 como imagem principal
A execução do programa com um segundo argumento de arquivo de imagem (a imagem principal) divide a imagem original em regiões com base na imagem principal. Cada uma dessas regiões é dividida em 2 ciclos separadamente, para que toda a confusão ocorra dentro das regiões e os pixels não sejam movidos de uma região para outra. Isso espalha os pixels sobre cada região e, portanto, as regiões se tornam uma cor manchada uniforme, mas com uma cor média ligeiramente diferente para cada região. Isso fornece uma aproximação aproximada da imagem principal, nas cores erradas.
A execução novamente troca os mesmos pares de pixels em cada região, para que cada região seja restaurada ao seu estado original e a imagem como um todo reapareça.
Graças à resposta do edc65 como a primeira a sugerir a divisão da imagem em regiões. Eu queria expandir isso para usar regiões arbitrárias, mas a abordagem de trocar tudo na região 1 por tudo na região 2 significava que as regiões tinham que ter o mesmo tamanho. Minha solução é manter as regiões isoladas umas das outras e simplesmente embaralhar cada região em si mesma. Como as regiões não precisam mais ter tamanho semelhante, torna-se mais simples aplicar regiões de formato arbitrário.
Código
Gravação de imagem JPEG
Os arquivos .jpg são processados muito rapidamente, mas com o custo de ficar muito quente. Isso deixa uma imagem queimada depois que o original é restaurado:
Mas, falando sério, um formato com perdas resultará na alteração leve de algumas cores dos pixels, o que por si só torna a saída inválida. Quando uma imagem principal é usada e o embaralhamento de pixels é restrito às regiões, toda a distorção é mantida na região em que ocorreu e depois se espalha uniformemente nessa região quando a imagem é restaurada. A diferença na distorção média entre as regiões deixa uma diferença visível entre elas; portanto, as regiões usadas no processo de embaralhamento ainda são visíveis na imagem restaurada.
A conversão para .png (ou qualquer formato sem perdas) antes da codificação garante que a imagem não codificada seja idêntica à original sem gravação ou distorção:
Pequenos detalhes
fonte
Aqui está uma transformação não aleatória para uma mudança
nx
vezesny
tempos das linhasA transformação é quase inversa, repetindo a transformação um total de
size_x
vezes (na direção x) retorna a imagem original. Eu não descobri a matemática exata, mas o uso de múltiplos inteirosint(log_2(size_x))
produz o melhor embaralhamento com as menores imagens fantasmasÉ assim que parecem as primeiras 20 iterações das etapas (nx = ny, observe o efeito de diferentes resoluções)
fonte
Mathematica
Isso é bem direto. Eu escolho
5 * nPixels
pares de coordenadas aleatórios e troco esses dois pixels (o que obscurece completamente a imagem). Para decifrar, faço o mesmo ao contrário. Obviamente, preciso propagar o PRNG para obter os mesmos pares de coordenadas nos dois passos.A única diferença entre as duas funções está
Reverse@
emunscramble
. Ambas as funções usam um objeto de imagem real. Você pode usá-los da seguinte maneira:out
ein
são idênticos. Aqui está o quescr
parece:fonte
FindPermutation
?{c, a, b}[[{2, 3, 1}]]
possa ser usado?C # (+ bônus para algoritmo simétrico)
Isso funciona ao encontrar um
x
tal quex^2 == 1 mod (number of pixels in image)
, e depois multiplicar o índice de cada pixel porx
, a fim de encontrar seu novo local. Isso permite que você use exatamente o mesmo algoritmo para embaralhar e decifrar uma imagem.fonte
1
(imagem original) emodulo-1
(imagem invertida / invertida). A maioria dos números tem soluções não triviais, mas existem algumas exceções, ao que parece . (relacionado com o primeiro-factorização demodulo
)1
gera a imagem original e-1
gera, por exemplo, imgur.com/EiE6VW2C #, auto-inverso, sem aleatoriedade
Se a imagem original tiver dimensões com potências de dois, cada linha e coluna será trocada pela linha e coluna que possui o padrão de bits invertido, por exemplo, para uma imagem de largura 256, a linha 0xB4 será trocada pela linha 0x2D. Imagens de outros tamanhos são divididas em retângulos com lados de potências de 2.
Primeira imagem:
Segunda imagem:
fonte
C #
Mesmo método para embaralhar e desembaralhar. Eu gostaria de receber sugestões para melhorar isso.
Resultados resulta em xadrez psicodélico
fonte
Python 2 (auto-inverso, sem aleatoriedade, sensível ao contexto)
Isso não ganhará nenhum prêmio por "menos reconhecível", mas talvez possa ser considerado "interessante". :-)
Eu queria criar algo sensível ao contexto, onde a confusão dos pixels realmente depende da própria imagem.
A idéia é bem simples: classifique todos os pixels de acordo com algum valor arbitrário derivado da cor do pixel e troque as posições do primeiro pixel nessa lista com o último, o segundo com o segundo e o último, e assim por diante.
Infelizmente, nessa abordagem simples, há um problema com pixels da mesma cor; portanto, para torná-lo inverso, meu programa ficou um pouco mais complicado ...
Este é o resultado:
Você pode obter resultados bastante diferentes alterando a função hash
f
:r-g-b
:r+g/2.**8+b/2.**16
:math.sin(r+g*2**8+b*2**16)
:(r+g+b)//600
:0
:fonte
Mathematica (+ bônus)
Isso recolhe os canais de cores e embaralha a imagem como uma longa lista de dados. O resultado é uma versão codificada ainda menos reconhecível porque não possui a mesma distribuição de cores do original (já que esses dados também foram codificados). Isso é mais óbvio na segunda imagem embaralhada, mas se você olhar atentamente, também verá o mesmo efeito na primeira. A função é inversa.
Houve um comentário de que isso pode não ser válido porque embaralha por canal. Eu acho que deveria ser, mas não é grande coisa. A única alteração necessária para embaralhar pixels inteiros (em vez de por canal) seria mudar
Flatten @ x
paraFlatten[x, 1]
:)Explicação
Define uma função
f
que utiliza uma matriz bidimensionalx
. A função usa o produto das dimensões da imagem como uma semente aleatória e depois nivela a matriz para uma lista unidimensionalf
(sombreada localmente). Em seguida, ele cria uma lista da forma em{1, 2, ... n}
quen
o comprimentof
permuta aleatoriamente essa lista, a particiona em segmentos de 2 (portanto, por exemplo,{{1, 2}, {3, 4}, ...}
(deixar o último número se as dimensões forem ímpares) e depois permutaf
trocando os valores em as posições indicadas em cada sub-lista recém-criada e, finalmente, remodela a lista permutada de volta às dimensões originais dex
.Flatten
O comando também recolhe os dados do canal em cada pixel. A função é inversa, porque os ciclos incluem apenas dois pixels cada.Uso
Aqui está usando
Flatten[x, 1]
.fonte
f @ f @ img1 // Image
é (na sintaxe completa)Image[f[f[img1]]]
Matlab (+ bônus)
Basicamente, alterno a posição de dois pixels aleatoriamente e identifico cada pixel que foi alternado, para que não seja alternado novamente. O mesmo script pode ser usado novamente para a 'descriptografia' porque eu redefino o gerador de números aleatórios a cada vez. Isso é feito até que quase todos os pixels sejam alternados (é por isso que o tamanho da etapa é maior que 2)
Edição: Acabei de ver que Martin Büttner usou uma abordagem semelhante - eu não pretendia copiar a idéia - comecei a escrever meu código quando não havia respostas, então, desculpe-me por isso. Eu ainda acho que minha versão usa algumas idéias diferentes =) (E meu algoritmo é muito mais ineficiente se você olhar para o ponto em que as duas coordenadas aleatórias são escolhidas ^^)
Imagens
Código
fonte
Mathematica-Use uma permutação para embaralhar e sua inversa para desembaralhar.
Uma imagem jpg é uma matriz tridimensional de
{r,g,b}
cores de pixel. (As três dimensões estruturam o conjunto de pixels por linha, coluna e cor). Ele pode ser achatado em uma lista de{r,g,b}
triplos, permutado de acordo com uma lista de ciclos "conhecida" e finalmente remontado em uma matriz das dimensões originais. O resultado é uma imagem embaralhada.Desembaralhar pega a imagem embaralhada e a processa com o reverso da lista de ciclos. Emite, sim, a imagem original.
Portanto, uma única função (no presente caso
scramble
) serve para embaralhar e também desembaralhar pixels em uma imagem.Uma imagem é inserida junto com um número inicial (para garantir que o gerador de números aleatórios esteja no mesmo estado para embaralhar e desembaralhar). Quando o parâmetro, reverse, é False, a função embaralha. Quando é True, a função será decodificada.
passeio
Os pixels são achatados e uma lista aleatória de ciclos é gerada. O permute usa ciclos para alternar as posições dos pixels na lista nivelada.
decifrar
A mesma função
scramble
é usada para desembaralhar. No entanto, a ordem da lista de ciclos é revertida.Exemplos
A mesma semente (37) é usada para embaralhar e desembaralhar.
Isso produz a imagem embaralhada da montanha. A figura abaixo mostra que a variável scrambledMount pode ser substituída pela imagem real da cena da montanha.
Agora nós executamos o inverso; scrambledMount é inserido e a imagem original é recuperada.
A mesma coisa para os círculos:
fonte
Pitão
Eu gosto desse quebra-cabeça, ele parecia interessante e eu vim com uma função envolvente e de movimento para aplicar na imagem.
Wraped
Eu li a imagem como um texto (da esquerda para a direita, para cima e para baixo) e a escrevi como uma concha de caracol.
Esta função é cíclica: existe um em N, f ^ (n) (x) = x por exemplo, para uma figura de 4 * 2, f (f (f (x))) = x
Movimento
Pego um número aleatório e movo cada coluna e alinhar a partir dela
Código
As fotos
Primeira rotação:
então permutação:
E com a última rotaion:
Quanto ao outro exemplo:
fonte
VB.NET (+ bônus)
Isso usa a idéia de flawr, graças a ele, no entanto, usa diferentes algoritmos de troca e verificação. O programa codifica e decodifica da mesma maneira.
Imagens de saída:
fonte
Depois de ser lembrado que isso está prestes a trocar pixels e não alterá-los, aqui está minha solução para isso:
Mexidos:
Restaurado:
Isso é feito aleatoriamente a ordem dos pixels, mas para poder restaurá-lo, a randomização é corrigida. Isso é feito usando um pseudo-aleatório com uma semente fixa e gera uma lista de índices que descrevem quais pixels trocar. Como a troca será a mesma, a mesma lista restaurará a imagem original.
Observe que o uso desse algoritmo em um formato de compactação com perdas não produzirá o mesmo resultado, pois o formato da imagem alterará os dados. Isso deve funcionar bem com qualquer codec sem perda, como PNG.
fonte
Mathematica
Definimos uma função auxiliar
h
e a função de embaralhamentoscramble
como:Depois de carregar uma imagem, você pode chamar
scramble[img, k]
ondek
é qualquer inteiro, para embaralhar a imagem. Ligar novamente com-k
decodificará. (Sek
estiver0
, então nenhuma alteração será feita.) Normalmente,k
deve ser escolhido algo como100
: o que fornece uma imagem bastante embaralhada:fonte
Matlab: embaralhamento de linhas e colunas com base em invariâncias de soma de linhas / colunas
Parecia um quebra-cabeça divertido, então eu pensei sobre isso e criei a seguinte função. Ele se baseia na invariância das somas de valor de pixel de linha e coluna durante o deslocamento circular: muda cada linha e depois cada coluna pela soma total dos valores de pixel da linha / coluna (assumindo uint8 para o número inteiro na variável shift ) Isso pode ser revertido deslocando cada coluna e depois a linha pelo valor da soma na direção oposta.
Não é tão bonito quanto os outros, mas gosto que não seja aleatório e totalmente especificado pela imagem - sem escolha de parâmetros.
Eu o projetei originalmente para mudar cada canal de cor separadamente, mas notei a especificação para mover apenas pixels completos.
fonte
Java
Este programa alterna aleatoriamente pixels (cria o mapeamento pixel a pixel), mas, em vez da função aleatória, usa Math.sin () (número inteiro x). É totalmente reversível. Com imagens de teste, ele cria alguns padrões.
Parâmetros: número inteiro (número de passes, número negativo para reverter, 0 não faz nada), imagem de entrada e imagem de saída (pode ser a mesma). O arquivo de saída deve estar no formato que usa compactação sem perdas.
1 passagem:
100 passes (leva alguns minutos para fazer):
Código:
fonte
Python 2.7 com PIL
Um pouco tarde para a festa, mas achei que seria divertido converter as imagens em mantas (e de volta, é claro). Primeiro, deslocamos as colunas para cima ou para baixo em 4 vezes o número das colunas (colunas pares para baixo, colunas ímpares para cima). Em seguida, deslocamos as linhas para a esquerda ou direita por 4 vezes o número da linha (colunas pares à esquerda, colunas ímpares à direita).
O resultado é bastante tartan.
Para reverter, apenas fazemos isso na ordem oposta e mudamos na quantidade oposta.
Código
Resultados
A manta da imagem 1:
A imagem da forma xadrez 2:
fonte
offset = x*xsize/ysize
eoffset = y*ysize/xsize
Mas, infelizmente, também não oculta a imagem.Python (+ bônus) - permutação dos pixels
Nesse método, cada pixel será colocado em outra posição, com a restrição de que o outro pixel seja colocado na primeira posição. Matematicamente, é uma permutação com duração de ciclo 2. Como tal, o método é o próprio inverso.
Em retrospecto, é muito semelhante ao mfvonh, mas essa submissão é em Python e eu tive que construir essa permutação por conta própria.
Primeira imagem de teste: Segunda imagem de teste:
fonte
Python 2.7 + PIL, inspiração nos quebra-cabeças deslizantes
Só tive outra ideia. Basicamente, esse método divide uma imagem em blocos de tamanhos iguais e, em seguida, embaralha sua ordem. Como o novo pedido é baseado em uma semente fixa, é possível reverter completamente o processo usando a mesma semente. Além disso, com o parâmetro adicional chamado granularidade, é possível obter resultados diferentes e irreconhecíveis.
Resultados:
Original
Granularidade 16
Granularidade 13
Granularidade 10
Granularidade 3
Granularidade 2
Granularidade 1
Original
Granularidade 16
Granularidade 13
Granularidade 10
Granularidade 3
Granularidade 2
Granularidade 1
Código:
fonte
47
94 linhas. 47 para codificação, 47 para decodificação.
codegolf-35005_ref.rb
(convertido em jpg)
(original reduzido)
fonte
Matlab com uma pitada de teoria dos grupos (+ bônus)
Nesta abordagem, assumimos que temos um número par de pixels totais. (Caso contrário, ignoramos apenas um pixel). Precisamos escolher metade dos pixels para trocar com a outra metade. Para isso, indexamos todos os pixels de
0
até2N-1
e consideramos esses índices como um grupo cíclico.Entre os primos, procuramos um número
p
que não seja muito pequeno nem muito grande, e que seja coprime para2N
a ordem do nosso grupo. Isso significag
gera nosso grupo ou{k*g mod 2N | k=0,1,...,2N-1} = {0,1,...,2N-1}
.Portanto, escolhemos os primeiros
N
múltiplos deg
um conjunto e todos os indeces restantes como o outro conjunto e trocamos o conjunto de pixels correspondente.Se
p
for escolhido da maneira correta, o primeiro conjunto será distribuído uniformemente por toda a imagem.Os dois casos de teste:
Um pouco fora do tópico, mas interessante:
Durante o teste, notei que se você o salvar em um jpg (com perda compactado) (em vez de um png sem perdas) e aplicar a transformação para frente e para trás, você verá rapidamente artefatos da compressão, isso mostra os resultados de dois rearranjos consecutivos :
Como você pode ver, a compactação jpg faz com que o resultado pareça quase preto e branco!
fonte
JavaScript (+ bônus) - repetidor de troca de pixels divididos
fonte
Python 2.7 + PIL, Scrambler de coluna / linha
Este método simplesmente embaralha as linhas e colunas da imagem. É possível embaralhar apenas uma das dimensões ou ambas. Além disso, a ordem da nova linha / coluna codificada é baseada em uma senha. Além disso, outra possibilidade é embaralhar toda a matriz de imagens sem considerar as dimensões.
Resultados:
Embaralhando a imagem inteira:
Misturando as colunas:
Misturando as linhas:
Misturando colunas e linhas:
Também tentei aplicar várias execuções à imagem, mas os resultados finais não diferiram muito, apenas a dificuldade de descriptografá-la.
Código:
fonte
C # WinForms
Imagem1:
Imagem 2:
Código fonte:
fonte
Python 3.6 + pypng
Riffle / Master Shuffle
Meu algoritmo aplica o shuffle riffle em uma direção e o shuffle master na outra (já que os dois são inversos um do outro), várias iterações cada, mas cada um é generalizado para se dividir em qualquer número de subgrupos em vez de apenas dois. O efeito é que você pode criar uma chave de permutação de várias iterações, pois a imagem não será restaurada sem conhecer a sequência exata de riffle e master shuffles. Uma sequência pode ser especificada com uma série de números inteiros, com números positivos representando riffles e números negativos representando mestres.
Eu embaralhei a paisagem com a tecla [3, -5, 2, 13, -7]:
Curiosamente, algumas coisas interessantes acontecem em [3, -5], onde ficam alguns artefatos da imagem original:
Aqui está o padrão abstrato embaralhado com a tecla [2, 3, 5, 7, -11, 13, -17]:
Se apenas um parâmetro estiver errado na chave, a reprodução aleatória não restaurará a imagem:
fonte