Cree un programa que pueda reorganizar píxeles en la imagen para que no pueda ser reconocido. Sin embargo, su programa debería poder convertirlo nuevamente a la imagen original.
Puede escribir dos funciones, para codificar y decodificar, sin embargo, una función que se aplica repetidamente da una imagen original (ejemplo en matemáticas f(x) = 1 - x
) es una ventaja.
También producir algún patrón en la salida también da bonificación.
La imagen puede representarse como una matriz 1D / 2D u objeto de imagen si su idioma lo admite. Tenga en cuenta que solo puede cambiar el orden de los píxeles.
Será lógico seleccionar como código ganador que produce una imagen menos reconocible, sin embargo, no sé cómo medirlo exactamente, todas las formas que puedo imaginar pueden ser engañadas. Por lo tanto, elegí esta pregunta como concurso de popularidad. ¡Permita que los usuarios elijan cuál es la mejor respuesta!
Imagen de prueba 1 (800 x 422 px): Imagen de prueba 2 (800 x 480 px): Proporcione la imagen de salida del código.
fuente
Respuestas:
Python 2.7 (con PIL): sin seudoaleatoriedad
Divido la imagen en 2 por 2 bloques (ignorando el resto) y gire cada bloque 180 grados, luego hago lo mismo con 3 por 3 bloques, luego 4, etc. hasta algún parámetro BLKSZ. Luego hago lo mismo para BLKSZ-1, luego BLKSZ-2, hasta 3, luego 2. Este método se invierte exactamente; la función de descifrar es la función de codificación.
El código :
Dependiendo del tamaño de bloque, puede hacer que el cálculo erradique todo parecido con la imagen original: (BLKSZ = 50)
O haga que el cálculo sea eficiente: (BLKSZ = 10)
fuente
BLKSZ = 10
paisaje es realmente genial!C #, Winform
Editar Cambiando la forma en que llena la matriz de coordenadas puede tener diferentes patrones - vea abajo
¿Te gusta este tipo de patrón?
Prima:
Intercambio aleatorio exactamente una vez todos los píxeles en la mitad superior con todos los píxeles en la mitad inferior. Repita el mismo procedimiento para descifrar (bonificación).
Código
Scramble.cs
Scramble.designer.cs
Program.cs
Marque 'Código inseguro' en la propiedad del proyecto para compilar.
Patrón complejo
Cambie la primera parte de la función de trabajo, hasta Application.DoEvents:
fuente
C, desenfoque arbitrario, fácilmente reversible
Tarde a la fiesta. Aquí está mi entrada!
Este método hace un desenfoque de aleatorización. Yo lo llamo scramblur . Es extremadamente simple En un bucle, elige un píxel aleatorio y luego lo intercambia con un píxel cercano elegido aleatoriamente en un modelo de lienzo toroidal. Usted especifica la distancia máxima que define lo que significa "píxel cercano" (1 significa elegir siempre un píxel adyacente), el número de iteraciones y, opcionalmente, un número inicial aleatorio. Cuanto mayor sea la distancia máxima y mayor sea el número de iteraciones, más borroso será el resultado.
Es reversible especificando un número negativo de iteraciones (esto es simplemente una conveniencia de interfaz de línea de comandos; en realidad no existe tal cosa como iteraciones negativas). Internamente, utiliza un LCPRNG de 64 bits personalizado (generador de números pseudoaleatorios congruenciales lineales) y genera previamente un bloque de valores. La tabla permite recorrer el bloque hacia adelante o hacia atrás para codificar o descifrar, respectivamente.
Manifestación
Para las dos primeras imágenes, a medida que se desplaza hacia abajo, cada imagen se desenfoca utilizando un desplazamiento máximo más alto: la más alta es la imagen original (por ejemplo, desplazamiento de 0 píxeles), seguida de 1, 2, 4, 8, 16, 32, 64 , 128 y finalmente 256. El recuento de iteraciones es 10⁶ = 1,000,000 para todas las imágenes a continuación.
Para las segundas dos imágenes, cada imagen se difumina usando un desplazamiento progresivamente más bajo , por ejemplo, más borroso a menos borroso, desde un desplazamiento máximo de 256 hasta 0. ¡Disfruta!
Y para las siguientes dos imágenes, puede ver las progresiones a tamaño completo aquí y aquí :
Código
Pirateé esto juntos en aproximadamente una hora mientras me despertaba esta mañana y casi no contiene documentación. Podría volver en unos días y agregar más documentación más tarde si la gente lo solicita.
fuente
Python 3.4
Cuando se alcanza la bonificación 2, al usar una imagen clave adicional, la bonificación 1 no se pierde. El programa todavía es auto inverso, siempre que se ejecute con la misma imagen clave nuevamente.
Uso estándar
Imagen de prueba 1:
Imagen de prueba 2:
Ejecutar el programa con un solo archivo de imagen como argumento guarda un archivo de imagen con los píxeles revueltos uniformemente sobre toda la imagen. Ejecutarlo nuevamente con la salida codificada guarda un archivo de imagen con la codificación aplicada nuevamente, lo que restaura el original ya que el proceso de codificación es inverso.
El proceso de aleatorización es inverso a sí mismo porque la lista de todos los píxeles se divide en 2 ciclos, de modo que cada píxel se intercambia con uno y solo otro píxel. Ejecutarlo por segunda vez intercambia cada píxel con el píxel con el que se intercambió por primera vez, volviendo todo a cómo comenzó. Si hay un número impar de píxeles, habrá uno que no se mueva.
Gracias a la respuesta de mfvonh como la primera en sugerir 2 ciclos.
Uso con una imagen clave
Aleatorización de la imagen de prueba 1 con la imagen de prueba 2 como imagen clave
Aleatorización de la imagen de prueba 2 con la imagen de prueba 1 como imagen clave
Ejecutar el programa con un segundo argumento de archivo de imagen (la imagen clave) divide la imagen original en regiones basadas en la imagen clave. Cada una de estas regiones se divide en 2 ciclos por separado, de modo que toda la codificación ocurre dentro de las regiones, y los píxeles no se mueven de una región a otra. Esto extiende los píxeles sobre cada región y, por lo tanto, las regiones se convierten en un color moteado uniforme, pero con un color promedio ligeramente diferente para cada región. Esto proporciona una aproximación muy aproximada de la imagen clave, en los colores incorrectos.
La ejecución de nuevo intercambia los mismos pares de píxeles en cada región, por lo que cada región se restaura a su estado original y la imagen en su conjunto vuelve a aparecer.
Gracias a la respuesta de edc65 como la primera en sugerir dividir la imagen en regiones. Quería ampliar esto para usar regiones arbitrarias, pero el enfoque de intercambiar todo en la región 1 con todo en la región 2 significaba que las regiones tenían que ser del mismo tamaño. Mi solución es mantener las regiones aisladas unas de otras, y simplemente mezclar cada región en sí misma. Como las regiones ya no necesitan tener un tamaño similar, se vuelve más simple aplicar regiones con formas arbitrarias.
Código
Grabación de imagen JPEG
Los archivos .jpg se procesan muy rápidamente, pero a costa de correr demasiado caliente. Esto deja una imagen posterior quemada cuando se restaura el original:
Pero en serio, un formato con pérdida dará como resultado que algunos de los colores de los píxeles se cambien ligeramente, lo que en sí mismo invalida la salida. Cuando se usa una imagen clave y la combinación aleatoria de píxeles se restringe a regiones, toda la distorsión se mantiene dentro de la región en la que sucedió, y luego se extiende uniformemente sobre esa región cuando se restaura la imagen. La diferencia en la distorsión promedio entre regiones deja una diferencia visible entre ellas, por lo que las regiones utilizadas en el proceso de codificación aún son visibles en la imagen restaurada.
La conversión a .png (o cualquier formato sin pérdidas) antes de codificar garantiza que la imagen sin codificar sea idéntica a la original sin quemaduras ni distorsiones:
Pequeños detalles
fuente
Aquí hay una transformación no aleatoria para un cambio
nx
tiemposny
vecesLa transformación es casi autoinversa, repitiendo la transformación un total de
size_x
veces (en dirección x) devuelve la imagen original. No descubrí las matemáticas exactas, pero el uso de múltiplos enterosint(log_2(size_x))
produce la mejor combinación con las imágenes fantasma más pequeñasAsí es como se ven los primeros pasos 20 iteraciones (nx = ny, tenga en cuenta el efecto de diferentes resoluciones)
fuente
Mathematica
Esto es bastante sencillo. Elijo
5 * nPixels
pares de coordenadas aleatorias y cambio esos dos píxeles (lo que oscurece completamente la imagen). Para descifrarlo hago lo mismo a la inversa. Por supuesto, necesito sembrar el PRNG para obtener los mismos pares de coordenadas en ambos pasos.La única diferencia entre las dos funciones está
Reverse@
enunscramble
. Ambas funciones toman un objeto de imagen real. Puede usarlos de la siguiente manera:out
yin
son idénticos Así es como sescr
ve:fuente
FindPermutation
?{c, a, b}[[{2, 3, 1}]]
se puede utilizar?C # (+ Bonificación por algoritmo simétrico)
Esto funciona encontrando un
x
tal quex^2 == 1 mod (number of pixels in image)
, y luego multiplicando el índice de cada píxel porx
para encontrar su nueva ubicación. Esto le permite utilizar exactamente el mismo algoritmo para codificar y descifrar una imagen.fuente
1
(imagen original) emodulo-1
(imagen invertida / invertida). La mayoría de los números tienen soluciones no triviales, pero parece que hay algunas excepciones . (relacionado con la factorización prima demodulo
)1
muestra la imagen original y muestra,-1
por ejemplo, imgur.com/EiE6VW2C #, autoinverso, sin aleatoriedad
Si la imagen original tiene dimensiones que son potencias de dos, entonces cada fila y columna se intercambia con la fila y columna que tiene el patrón de bits invertido, por ejemplo, para una imagen de ancho 256, la fila 0xB4 se intercambia con la fila 0x2D. Las imágenes de otros tamaños se dividen en rectángulos con lados de potencias de 2.
Primera imagen
Segunda imagen:
fuente
C#
El mismo método para codificar y descifrar. Agradecería sugerencias para mejorar esto.
Resultados de resultados en cuadros psicodélicos
fuente
Python 2 (autoinverso, sin aleatoriedad, sensible al contexto)
Esto no ganará ningún premio por "menos reconocible", pero tal vez pueda calificar como "interesante". :-)
Quería hacer algo sensible al contexto, donde la codificación de los píxeles realmente depende de la imagen misma.
La idea es bastante simple: ordenar todos los píxeles de acuerdo con algún valor arbitrario derivado del color del píxel y luego intercambiar las posiciones del primer píxel en esa lista con el último, el segundo con el segundo al último, y así sucesivamente.
Desafortunadamente, en este enfoque simple hay un problema con los píxeles del mismo color, por lo que para que sea autoinverso, mi programa se volvió un poco más complicado ...
Este es el resultado:
Puede lograr resultados bastante diferentes cambiando la función 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
:fuente
Mathematica (+ bonificación)
Esto contrae los canales de color y codifica la imagen como una larga lista de datos. El resultado es una versión codificada aún menos reconocible porque no tiene la misma distribución de colores que la original (ya que los datos también fueron codificados). Esto es más obvio en la segunda imagen codificada, pero si observa de cerca verá también el mismo efecto en la primera. La función es su propio inverso.
Hubo un comentario de que esto puede no ser válido porque codifica por canal. Creo que debería ser, pero no es gran cosa. El único cambio necesario para codificar píxeles enteros (en lugar de por canal) sería cambiar
Flatten @ x
aFlatten[x, 1]
:)Explicación
Define una función
f
que toma una matriz bidimensionalx
. La función utiliza el producto de las dimensiones de la imagen como una semilla aleatoria, y luego aplana la matriz a una lista unidimensionalf
(sombreada localmente). Luego crea una lista de la forma{1, 2, ... n}
donden
está la longitud def
, al azar permuta esa lista, la divide en segmentos de 2 (por ejemplo,{{1, 2}, {3, 4}, ...}
(soltando el último número si las dimensiones son impares), y luego permutaf
intercambiando los valores en las posiciones indicadas en cada sublista que acaba de crear, y finalmente vuelve a dar forma a la lista permutada a las dimensiones originales dex
. Se codifica por canal porque además de contraer las dimensiones de la imagen,Flatten
El comando también contrae los datos del canal en cada píxel. La función es su propio inverso porque los ciclos incluyen solo dos píxeles cada uno.Uso
Aquí está usando
Flatten[x, 1]
.fuente
f @ f @ img1 // Image
es (en sintaxis completa)Image[f[f[img1]]]
Matlab (+ bonificación)
Básicamente, cambio la posición de dos píxeles al azar y etiqueto cada píxel que se ha cambiado para que no se vuelva a cambiar. El mismo script se puede usar nuevamente para el 'descifrado' porque reinicio el generador de números aleatorios cada vez. Esto se hace hasta que casi todos los píxeles se cambian (es por eso que el tamaño de pasos es mayor que 2)
EDITAR: Acabo de ver que Martin Büttner usó un enfoque similar, no tenía la intención de copiar la idea, comencé a escribir mi código cuando no había respuestas, lo siento mucho. Todavía creo que mi versión usa algunas ideas diferentes =) (Y mi algoritmo es mucho más ineficiente si nos fijamos en el bit donde se seleccionan las dos coordenadas aleatorias ^^)
Imágenes
Código
fuente
Mathematica-Use una permutación para codificar y su inverso para descifrar.
Una imagen jpg es una matriz tridimensional de
{r,g,b}
colores de píxeles. (Las 3 dimensiones estructuran el conjunto de píxeles por fila, columna y color). Se puede aplanar en una lista de{r,g,b}
triples, luego se puede permutar de acuerdo con una lista de ciclos "conocida" y finalmente se puede volver a ensamblar en una matriz de las dimensiones originales. El resultado es una imagen revuelta.Descifrar toma la imagen codificada y la procesa con el reverso de la lista de ciclos. Produce, sí, la imagen original.
Entonces, una sola función (en el presente caso
scramble
) sirve para codificar y descifrar píxeles en una imagen.Se ingresa una imagen junto con un número inicial (para garantizar que el generador de números aleatorios estará en el mismo estado para codificar y descifrar). Cuando el parámetro, reverse, es False, la función se codificará. Cuando es verdadero, la función se descifrará.
lucha
Los píxeles se aplanan y se genera una lista aleatoria de ciclos. Permute usa ciclos para cambiar las posiciones de los píxeles en la lista aplanada.
descifrar
La misma función,
scramble
se utiliza para descifrar. Sin embargo, el orden de la lista de ciclos se invierte.Ejemplos
La misma semilla (37) se usa para codificar y descifrar.
Esto produce la imagen revuelta de la montaña. La siguiente imagen muestra que la variable scrambledMount puede sustituirse por la imagen real de la escena de la montaña.
Ahora corremos el inverso; scrambledMount se ingresa y se recupera la imagen original.
Lo mismo para los círculos:
fuente
Pitón
Me gusta este rompecabezas, parecía interesante y llegué con una función de envoltura y movimiento para aplicar en la imagen.
Envuelto
Leo la imagen como un texto (de izquierda a derecha, arriba y abajo) y la escribo como una concha de caracol.
Esta función es cíclica: hay un en N, f ^ (n) (x) = x, por ejemplo, para una imagen de 4 * 2, f (f (f (x))) = x
Movimiento
Tomo un número aleatorio y muevo cada columna y línea de él
Código
Imágenes
Primera rotación:
entonces permutación:
Y con la última rotación:
En cuanto al otro ejemplo:
fuente
VB.NET (+ bonificación)
Esto utiliza la idea de flawr, gracias a él, sin embargo, utiliza diferentes algoritmos de intercambio y verificación. El programa codifica y decodifica de la misma manera.
Imágenes de salida:
fuente
Después de recordar que esto está a punto de intercambiar píxeles y no alterarlos, aquí está mi solución para esto:
Revuelto:
Restaurado:
Esto se hace aleatorizando el orden de píxeles, pero para poder restaurarlo, la aleatorización es fija. Esto se hace utilizando un pseudoaleatorio con una semilla fija y genera una lista de índices que describen qué píxeles intercambiar. Como el intercambio será el mismo, la misma lista restaurará la imagen original.
Tenga en cuenta que el uso de este algoritmo en un formato de compresión con pérdida no producirá el mismo resultado, ya que el formato de imagen alterará los datos. Esto debería funcionar bien con cualquier códec sin pérdidas como PNG.
fuente
Mathematica
Definimos una función auxiliar
h
y la función de codificaciónscramble
como:Después de cargar una imagen, puede llamar a
scramble[img, k]
dondek
está cualquier número entero para codificar la imagen. Llamar de nuevo con-k
se descifrará. (Sik
es así0
, entonces no se realiza ningún cambio). Pork
lo general, debe elegirse para ser algo así100
, lo que da una imagen bastante codificada:fuente
Matlab: codificación de filas y columnas basada en variaciones de suma de filas / columnas
Esto parecía un rompecabezas divertido, así que lo pensé y se me ocurrió la siguiente función. Se basa en la invariancia de las sumas de valor de píxel de fila y columna durante el desplazamiento circular: desplaza cada fila, luego cada columna, por la suma total de los valores de píxel de la fila / columna (suponiendo un uint8 para el número entero en la variable de desplazamiento ) Esto se puede revertir desplazando cada columna y luego remar por su valor de suma en la dirección opuesta.
No es tan bonito como los demás, pero me gusta que no sea aleatorio y esté completamente especificado por la imagen, sin elegir parámetros.
Originalmente lo diseñé para cambiar cada canal de color por separado, pero luego noté la especificación para mover solo píxeles completos.
fuente
Java
Este programa intercambia píxeles al azar (crea mapeo de píxel a píxel), pero en lugar de una función aleatoria, usa Math.sin () (entero x). Es totalmente reversible. Con imágenes de prueba crea algunos patrones.
Parámetros: número entero (número de pasadas, número negativo para revertir, 0 no hace nada), imagen de entrada e imagen de salida (puede ser lo mismo). El archivo de salida debe estar en formato que use compresión sin pérdidas.
1 pase:
100 pases (se tarda unos minutos en hacerlo):
Código:
fuente
Python 2.7 con PIL
Un poco tarde para la fiesta, pero pensé que sería divertido convertir las imágenes en cuadros (y al revés, por supuesto). Primero, desplazamos las columnas hacia arriba o hacia abajo 4 veces el número de columnas (columnas pares hacia abajo, columnas impares hacia arriba). Luego, desplazamos las filas hacia la izquierda o hacia la derecha 4 veces el número de la fila (columnas pares a la izquierda, columnas impares a la derecha).
El resultado es bastante tartán.
Para revertir, solo hacemos esto en el orden opuesto y cambiamos por la cantidad opuesta.
Código
Resultados
La tela escocesa de la imagen 1:
La imagen en forma de cuadros 2:
fuente
offset = x*xsize/ysize
yoffset = y*ysize/xsize
, desafortunadamente, realmente no oculta la imagen también.Python (+ bonus) - permutación de los píxeles
En este método, cada píxel se colocará en otra posición, con la restricción de que el otro píxel se colocará en la primera posición. Matemáticamente, es una permutación con la longitud del ciclo 2. Como tal, el método es su propio inverso.
En retrospectiva, es muy similar a mfvonh, pero esta presentación está en Python y tuve que construir esa permutación yo mismo.
Primera imagen de prueba: Segunda imagen de prueba:
fuente
Python 2.7 + PIL, inspiración de los rompecabezas deslizantes
Acabo de tener otra idea. Básicamente, este método divide una imagen en bloques de igual tamaño y luego baraja su orden. Dado que el nuevo orden se basa en una semilla fija, es posible revertir completamente el proceso usando la misma semilla. Además, con el parámetro adicional llamado granularidad, es posible lograr resultados diferentes e irreconocibles.
Resultados:
Original
Granularidad 16
Granularidad 13
Granularidad 10
Granularidad 3
Granularidad 2
Granularidad 1
Original
Granularidad 16
Granularidad 13
Granularidad 10
Granularidad 3
Granularidad 2
Granularidad 1
Código:
fuente
47
94 líneas. 47 para codificar, 47 para decodificar.
codegolf-35005_ref.rb
(convertido a jpg)
(original reducido)
fuente
Matlab con una pizca de teoría de grupo (+ bonus)
En este enfoque, suponemos que tenemos un número par de píxeles totales. (Si no, simplemente ignoramos un píxel). Por lo tanto, debemos elegir la mitad de los píxeles para intercambiar con la otra mitad. Para esto, indexamos todos los píxeles desde
0
hasta2N-1
y consideramos estos índices como un grupo cíclico.Entre los números primos buscamos un número
p
que no sea demasiado pequeño ni demasiado grande, y que sea coprimo para2N
el orden de nuestro grupo. Esto significa queg
genera nuestro grupo o{k*g mod 2N | k=0,1,...,2N-1} = {0,1,...,2N-1}
.Por lo tanto, elegimos los primeros
N
múltiplos deg
como un conjunto, y todos los indeces restantes como el otro conjunto, y simplemente intercambiamos el conjunto de píxeles correspondiente.Si
p
se elige de la manera correcta, el primer conjunto se distribuye uniformemente en toda la imagen.Los dos casos de prueba:
Ligeramente fuera de tema pero interesante:
Durante las pruebas, noté que si lo guarda en un jpg (comprimido con pérdida) (en lugar de un png comprimido sin pérdida) y aplica la transformación de un lado a otro, verá rápidamente artefactos de la compresión, esto muestra los resultados de dos reordenamientos consecutivos :
Como puede ver, la compresión jpg hace que el resultado se vea casi en blanco y negro.
fuente
JavaScript (+ bonificación) - repetidor de intercambio de división de píxeles
fuente
Python 2.7 + PIL, Scrambler de columna / fila
Este método simplemente codifica las filas y columnas de la imagen. Es posible mezclar solo una de las dimensiones o ambas. Además, el orden de la nueva fila / columna codificada se basa en una contraseña. Además, otra posibilidad es mezclar toda la matriz de imágenes sin tener en cuenta las dimensiones.
Resultados:
Mezclando toda la imagen:
Aleatorizando las columnas:
Aleatorizando las filas:
Mezclando columnas y filas:
También intenté aplicar varias corridas a la imagen, pero los resultados finales no diferían mucho, solo la dificultad para descifrarlo.
Código:
fuente
C # Winforms
Imagen1:
Imagen 2:
Código fuente:
fuente
Python 3.6 + pypng
Riffle / Master Shuffle
Mi algoritmo aplica el riffle shuffle en una dirección y un master shuffle en la otra (dado que los dos son inversos entre sí), varias iteraciones cada una, pero cada una se generaliza para dividirse en cualquier número de subgrupos en lugar de solo dos. El efecto es que podría crear una clave de permutación de iteración múltiple, ya que la imagen no se restaurará sin conocer la secuencia exacta de riffle y shuffle maestro. Se puede especificar una secuencia con una serie de enteros, con números positivos que representan rifles y números negativos que representan maestros.
Barajé el paisaje con la tecla [3, -5, 2, 13, -7]:
Curiosamente, algunas cosas interesantes suceden desde [3, -5], donde quedan algunos artefactos de la imagen original:
Aquí está el patrón abstracto barajado con la tecla [2, 3, 5, 7, -11, 13, -17]:
Si solo hay un parámetro incorrecto en la clave, la desorganización no restaurará la imagen:
fuente